🚀 Big News:Socket Has Acquired Secure Annex.Learn More
Socket
Book a DemoSign in
Socket

@evo/fetch-io

Package Overview
Dependencies
Maintainers
14
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@evo/fetch-io - npm Package Compare versions

Comparing version
2.3.1
to
3.0.0
+10
babel.config.js
module.exports = (api) => {
api.cache(false);
return {
presets: [
['@babel/preset-env', {targets: {node: 'current'}}],
'@babel/preset-typescript',
],
}
}
# CHANGELOG
## 3.0.0 *(23.11.2021)*
- Покрытия типами
- Обновление пакета @evo/user-info до 3.0.1
## 2.3.1 *(24.09.2021)*
- Замена устаревшего пакета cookies-js на свежий js-cookie
- Обновление пакета @evo/user-info до 2.0.5
export declare function getMyHost(): string | null;
export declare function setMyHost(host: string | null): void;
export declare function getSouldFetchPromUser(): boolean;
export declare function setSouldFetchPromUser(value: boolean): void;
export declare class FetchError<R> extends Error {
name: string;
message: string;
data: ({
status: 'error';
errors: string[];
} | R) | null;
response: Response;
constructor(name: string, message: string, data: ({
status: 'error';
errors: string[];
} | R) | null, response: Response);
}
import 'whatwg-fetch';
import { ParamsType, RequestInfoType } from './types';
export declare function GET<T>(url: string, params?: ParamsType | string, opts?: RequestInfoType | Record<string, unknown>): Promise<T | null>;
export declare function getJSON<T>(url: string, params?: ParamsType | string): Promise<T | null>;
export declare const POST: <T>(url: string, params?: string | ParamsType | undefined, opts?: RequestInfoType | Record<string, unknown>) => Promise<T | null>;
export declare const PUT: <T>(url: string, params?: string | ParamsType | undefined, opts?: RequestInfoType | Record<string, unknown>) => Promise<T | null>;
export declare const DELETE: <T>(url: string, params?: string | ParamsType | undefined, opts?: RequestInfoType | Record<string, unknown>) => Promise<T | null>;
export declare const my: {
GET: <T>(rawUrl: string, params?: string | ParamsType | undefined, opts?: RequestInfoType | Record<string, unknown> | undefined) => Promise<T | null>;
getJSON: <T>(rawUrl: string, params?: string | ParamsType | undefined, opts?: RequestInfoType | Record<string, unknown> | undefined) => Promise<T | null>;
POST: <T>(rawUrl: string, params?: string | ParamsType | undefined, opts?: RequestInfoType | Record<string, unknown> | undefined) => Promise<T | null>;
PUT: <T>(rawUrl: string, params?: string | ParamsType | undefined, opts?: RequestInfoType | Record<string, unknown> | undefined) => Promise<T | null>;
DELETE: <T>(rawUrl: string, params?: string | ParamsType | undefined, opts?: RequestInfoType | Record<string, unknown> | undefined) => Promise<T | null>;
};
export declare function init(host: string, userFetch?: boolean): void;
export declare type PrimitivesType = number | string | boolean | null | undefined | {
[name: string]: PrimitivesType;
};
export declare type ValuesType = PrimitivesType | Array<PrimitivesType>;
export declare type ParamsType = Record<string, ValuesType>;
export declare type RequestInfoType = {
cache?: RequestCache;
credentials?: RequestCredentials;
destination?: RequestDestination;
headers: {
Accept: string;
'X-Requested-With': string;
'Content-Type'?: string;
'X-CSRFToken'?: string;
'X-PromUserID'?: number;
};
integrity?: string;
isHistoryNavigation?: boolean;
isReloadNavigation?: boolean;
keepalive?: boolean;
mode?: RequestMode;
redirect?: RequestRedirect;
referrer?: string;
referrerPolicy?: ReferrerPolicy;
signal?: AbortSignal;
multipart?: boolean;
method: string;
};
export interface DefaultOptionsType {
headers: {
Accept: string;
'X-Requested-With': string;
'Content-Type'?: string;
'X-CSRFToken'?: string;
'X-PromUserID'?: number;
};
body?: BodyInit | null;
method: string;
credentials: string;
multipart?: boolean;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
import { ParamsType, PrimitivesType, ValuesType } from './types';
export declare function isAbsolute(url: string): boolean;
export declare const addGetParam: (url: string, key: string, value: PrimitivesType) => string;
export declare const getParamByName: (paramName: string, url?: string) => string;
export declare function objectToPairs(obj: ParamsType): Array<ValuesType>;
export declare const addGetParams: (url: string, keyValues?: string | ParamsType | undefined, skipEncode?: boolean | undefined) => string;
"use strict";
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.addGetParams = exports.objectToPairs = exports.getParamByName = exports.addGetParam = exports.isAbsolute = void 0;
function isAbsolute(url) {
return /^https?:\/\/|^\/\//i.test(url);
}
exports.isAbsolute = isAbsolute;
var addGetParam = function (url, key, value) {
var param = value ? key + "=" + value : key;
var paramSeparator = url.indexOf('?') !== -1 ? '&' : '?';
return "" + url + paramSeparator + param;
};
exports.addGetParam = addGetParam;
var getParamByName = function (paramName, url) {
if (url === void 0) { url = location.search; }
var name = paramName.replace(/[[]/, '\\[').replace(/[\]]/, '\\]');
var regexS = "[\\?&]" + name + "=([^&#]*)";
var regex = new RegExp(regexS);
var results = regex.exec(url);
if (results) {
return decodeURIComponent(results[1].replace(/\+/g, ' '));
}
return '';
};
exports.getParamByName = getParamByName;
function objectToPairs(obj) {
return Object.keys(obj).reduce(function (base, key) {
var e_1, _a;
var value = obj[key];
if (Array.isArray(value)) {
try {
for (var value_1 = __values(value), value_1_1 = value_1.next(); !value_1_1.done; value_1_1 = value_1.next()) {
var item = value_1_1.value;
base.push([key, item]);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (value_1_1 && !value_1_1.done && (_a = value_1.return)) _a.call(value_1);
}
finally { if (e_1) throw e_1.error; }
}
}
else {
base.push([key, value]);
}
return base;
}, []);
}
exports.objectToPairs = objectToPairs;
var addGetParams = function (url, keyValues, skipEncode) {
if (!keyValues) {
return url;
}
var keyVals = keyValues;
if (!Array.isArray(keyValues) && typeof keyValues === 'object') {
keyVals = objectToPairs(keyValues);
}
return keyVals.reduce(function (base, _a) {
var _b = __read(_a, 2), key = _b[0], value = _b[1];
var encodedValue = value !== undefined
? "" + (skipEncode ? value : encodeURIComponent(value))
: '';
return (0, exports.addGetParam)(base, key, encodedValue);
}, url);
};
exports.addGetParams = addGetParams;
import { DefaultOptionsType, ParamsType, RequestInfoType } from './types';
import { DELETE, GET, getJSON, POST, PUT } from './index';
export declare function isObject<T>(item: T): boolean;
export declare function isAbortSignal(object: any): boolean;
export declare function mergeDeep(target: any, ...sources: any): any;
export declare function checkResponseStatus<T>(data: T, response: Response): Response;
export declare function checkDataStatus<T extends {
status: string;
}>(data: T, response: Response): T;
export declare function parseJSON(resp: Response): Promise<any>;
export declare function getDefaultOptions(method: string): DefaultOptionsType;
export declare function applyOpts(options: DefaultOptionsType, opts: RequestInfoType | Record<string, unknown>): any;
export declare function formatBody(params?: ParamsType | string, opts?: RequestInfoType | Record<string, unknown>): string | ParamsType | undefined;
export declare function maybeAddMy(url: string): string;
export declare function fetchJSON<T>(url: string, info: any): Promise<T | null>;
export declare function unsafeMethodFactory(method: string): <T>(url: string, params?: string | ParamsType | undefined, opts?: RequestInfoType | Record<string, unknown>) => Promise<T | null>;
export declare const makeMy: (methodFunc: typeof GET | typeof POST | typeof PUT | typeof DELETE | typeof getJSON) => <T>(rawUrl: string, params?: string | ParamsType | undefined, opts?: RequestInfoType | Record<string, unknown> | undefined) => Promise<T | null>;
+7
-13
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getMyHost = getMyHost;
exports.setMyHost = setMyHost;
exports.getSouldFetchPromUser = getSouldFetchPromUser;
exports.setSouldFetchPromUser = setSouldFetchPromUser;
Object.defineProperty(exports, "__esModule", { value: true });
exports.setSouldFetchPromUser = exports.getSouldFetchPromUser = exports.setMyHost = exports.getMyHost = void 0;
var myHost = null;
var souldFetchPromUser = true;
function getMyHost() {
return myHost;
}
exports.getMyHost = getMyHost;
function setMyHost(host) {
myHost = host;
}
exports.setMyHost = setMyHost;
function getSouldFetchPromUser() {
return souldFetchPromUser;
}
exports.getSouldFetchPromUser = getSouldFetchPromUser;
function setSouldFetchPromUser(value) {
souldFetchPromUser = value;
}
}
exports.setSouldFetchPromUser = setSouldFetchPromUser;

@@ -1,26 +0,31 @@

'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.FetchNetworkError = FetchNetworkError;
exports.FetchDataError = FetchDataError;
function FetchNetworkError(message, data, response) {
this.name = 'FetchNetworkError';
this.message = message;
this.response = response;
this.data = data;
}
FetchNetworkError.prototype = Object.create(Error.prototype);
FetchNetworkError.prototype.constructor = FetchNetworkError;
function FetchDataError(message, data, response) {
this.name = 'FetchDataError';
this.message = message;
this.response = response;
this.data = data;
}
FetchDataError.prototype = Object.create(Error.prototype);
FetchDataError.prototype.constructor = FetchDataError;
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.FetchError = void 0;
var FetchError = /** @class */ (function (_super) {
__extends(FetchError, _super);
function FetchError(name, message, data, response) {
var _this = _super.call(this) || this;
_this.name = name;
_this.message = message;
_this.response = response;
_this.data = data;
return _this;
}
return FetchError;
}(Error));
exports.FetchError = FetchError;

@@ -1,23 +0,27 @@

'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
exports.my = exports.DELETE = exports.PUT = exports.POST = undefined;
exports.GET = GET;
exports.getJSON = getJSON;
exports.init = init;
require('whatwg-fetch');
var _url = require('@evo/prom-utils/lib/url');
var _utils = require('./utils');
var _config = require('./config');
var config = _interopRequireWildcard(_config);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.init = exports.my = exports.DELETE = exports.PUT = exports.POST = exports.getJSON = exports.GET = void 0;
require("whatwg-fetch");
var url_1 = require("./url");
var utils_1 = require("./utils");
var config = __importStar(require("./config"));
/*

@@ -29,10 +33,9 @@ Example:

*/
function GET(url, params) {
var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var urlWithParams = (0, _url.addGetParams)(url, params);
var options = (0, _utils.applyOpts)((0, _utils.getDefaultOptions)('GET'), opts);
return (0, _utils.fetchJSON)(urlWithParams, options);
function GET(url, params, opts) {
if (opts === void 0) { opts = {}; }
var urlWithParams = (0, url_1.addGetParams)(url, params);
var options = (0, utils_1.applyOpts)((0, utils_1.getDefaultOptions)('GET'), opts);
return (0, utils_1.fetchJSON)(urlWithParams, options);
}
exports.GET = GET;
/*

@@ -45,6 +48,6 @@ Example:

function getJSON(url, params) {
var urlWithParams = (0, _url.addGetParams)(url, params);
return (0, _utils.fetchJSON)(urlWithParams, { method: 'GET' });
var urlWithParams = (0, url_1.addGetParams)(url, params);
return (0, utils_1.fetchJSON)(urlWithParams, { method: 'GET' });
}
exports.getJSON = getJSON;
/*

@@ -56,4 +59,3 @@ Example:

*/
var POST = exports.POST = (0, _utils.unsafeMethodFactory)('POST');
exports.POST = (0, utils_1.unsafeMethodFactory)('POST');
/*

@@ -65,4 +67,3 @@ Example:

*/
var PUT = exports.PUT = (0, _utils.unsafeMethodFactory)('PUT');
exports.PUT = (0, utils_1.unsafeMethodFactory)('PUT');
/*

@@ -74,4 +75,3 @@ Example:

*/
var DELETE = exports.DELETE = (0, _utils.unsafeMethodFactory)('DELETE');
exports.DELETE = (0, utils_1.unsafeMethodFactory)('DELETE');
/*

@@ -81,15 +81,14 @@ Wraps methods with function that will transform the first

*/
var my = exports.my = {
GET: (0, _utils.makeMy)(GET),
getJSON: (0, _utils.makeMy)(getJSON),
POST: (0, _utils.makeMy)(POST),
PUT: (0, _utils.makeMy)(PUT),
DELETE: (0, _utils.makeMy)(DELETE)
exports.my = {
GET: (0, utils_1.makeMy)(GET),
getJSON: (0, utils_1.makeMy)(getJSON),
POST: (0, utils_1.makeMy)(exports.POST),
PUT: (0, utils_1.makeMy)(exports.PUT),
DELETE: (0, utils_1.makeMy)(exports.DELETE),
};
function init(host) {
var userFetch = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
config.setMyHost(host);
config.setSouldFetchPromUser(userFetch);
}
function init(host, userFetch) {
if (userFetch === void 0) { userFetch = true; }
config.setMyHost(host);
config.setSouldFetchPromUser(userFetch);
}
exports.init = init;

@@ -1,123 +0,122 @@

'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
exports.makeMy = exports.fetchJSON = exports.isAbortSignal = undefined;
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var fetchJSON = exports.fetchJSON = function () {
var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(url, info) {
var response, data;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return fetch(url, info);
case 2:
response = _context.sent;
if (!(!isOkResponse(response) && !isJSONResp(response))) {
_context.next = 5;
break;
}
throw new _errors.FetchNetworkError('Bad status ' + response.status + ' \'' + response.statusText + '\'', null, response);
case 5:
if (!(response.status === 204)) {
_context.next = 8;
break;
}
// 204 response cannot contain a message body
fetchDebugInfo(url, response);
return _context.abrupt('return', null);
case 8:
_context.next = 10;
return response.json();
case 10:
data = _context.sent;
// Check must throw an error if fails
checkResponseStatus(data, response);
checkDataStatus(data, response);
fetchDebugInfo(url, response);
return _context.abrupt('return', data);
case 15:
case 'end':
return _context.stop();
}
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
}, _callee, this);
}));
return function fetchJSON(_x2, _x3) {
return _ref.apply(this, arguments);
};
}();
exports.isObject = isObject;
exports.mergeDeep = mergeDeep;
exports.checkResponseStatus = checkResponseStatus;
exports.checkDataStatus = checkDataStatus;
exports.parseJSON = parseJSON;
exports.getDefaultOptions = getDefaultOptions;
exports.applyOpts = applyOpts;
exports.formatBody = formatBody;
exports.maybeAddMy = maybeAddMy;
exports.unsafeMethodFactory = unsafeMethodFactory;
var _url = require('@evo/prom-utils/lib/url');
var _userInfo = require('@evo/user-info');
var _errors = require('./errors');
var _config = require('./config');
var config = _interopRequireWildcard(_config);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.makeMy = exports.unsafeMethodFactory = exports.fetchJSON = exports.maybeAddMy = exports.formatBody = exports.applyOpts = exports.getDefaultOptions = exports.parseJSON = exports.checkDataStatus = exports.checkResponseStatus = exports.mergeDeep = exports.isAbortSignal = exports.isObject = void 0;
var user_info_1 = require("@evo/user-info");
var url_1 = require("./url");
var errors_1 = require("./errors");
var config = __importStar(require("./config"));
var CSRF_TOKEN_HEADER = 'X-CSRFToken';
var PROMUSER_HEADER = 'X-PromUserID';
function isObject(item) {
return item && (typeof item === 'undefined' ? 'undefined' : _typeof(item)) === 'object' && !Array.isArray(item);
return (item && typeof item === 'object' && !Array.isArray(item));
}
exports.isObject = isObject;
var NAME = Symbol.toStringTag;
var isAbortSignal = exports.isAbortSignal = function isAbortSignal(object) {
return (typeof object === 'undefined' ? 'undefined' : _typeof(object)) === 'object' && (object[NAME] === 'AbortSignal' || object[NAME] === 'EventTarget');
};
function isAbortSignal(object) {
return (typeof object === 'object' &&
(object[NAME] === 'AbortSignal' || object[NAME] === 'EventTarget'));
}
exports.isAbortSignal = isAbortSignal;
function mergeDeep(target) {
for (var _len = arguments.length, sources = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
sources[_key - 1] = arguments[_key];
var sources = [];
for (var _i = 1; _i < arguments.length; _i++) {
sources[_i - 1] = arguments[_i];
}
if (!sources.length) return target;
if (!sources.length)
return target;
var source = sources.shift();
if (!source)
return target;
if (isObject(target) && isObject(source)) {
Object.keys(source).forEach(function (key) {
if (isObject(source[key]) && (key !== 'signal' || !isAbortSignal(source[key]))) {
if (!target[key]) Object.assign(target, _defineProperty({}, key, {}));
var _a, _b;
if (isObject(source[key]) &&
(key !== 'signal' || !isAbortSignal(source[key]))) {
if (!target[key])
Object.assign(target, (_a = {}, _a[key] = {}, _a));
mergeDeep(target[key], source[key]);
} else {
Object.assign(target, _defineProperty({}, key, source[key]));
}
else {
Object.assign(target, (_b = {}, _b[key] = source[key], _b));
}
});

@@ -127,25 +126,25 @@ }

}
exports.mergeDeep = mergeDeep;
function isOkResponse(response) {
return response.status >= 200 && response.status < 300;
}
function isErrorDataStatus(data) {
return data && data.status && data.status === 'error';
return Boolean(data && data.status && data.status === 'error');
}
function checkResponseStatus(data, response) {
if (isOkResponse(response)) return response;
throw new _errors.FetchNetworkError('Bad status ' + response.status + ' \'' + response.statusText + '\'', data, response);
if (isOkResponse(response))
return response;
throw new errors_1.FetchError('FetchNetworkError', "Bad status " + response.status + " '" + response.statusText + "'", data, response);
}
exports.checkResponseStatus = checkResponseStatus;
function checkDataStatus(data, response) {
if (!isErrorDataStatus(data)) return data;
throw new _errors.FetchDataError('Data error status', data, response);
if (!isErrorDataStatus(data))
return data;
throw new errors_1.FetchError('FetchDataError', 'Data error status', data, response);
}
exports.checkDataStatus = checkDataStatus;
function parseJSON(resp) {
return resp.json();
}
exports.parseJSON = parseJSON;
function getDefaultHeaders() {

@@ -158,3 +157,2 @@ return {

}
function getDefaultOptions(method) {

@@ -166,11 +164,9 @@ if (!method) {

method: method,
credentials: 'include', // need this for CORS
headers: getDefaultHeaders()
credentials: 'include',
headers: getDefaultHeaders(),
};
return defaultOptions;
}
function applyOpts(options) {
var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
exports.getDefaultOptions = getDefaultOptions;
function applyOpts(options, opts) {
options = mergeDeep(options, opts);

@@ -183,4 +179,5 @@ if (opts.multipart) {

}
exports.applyOpts = applyOpts;
function formatBody(params, opts) {
if (opts === void 0) { opts = {}; }
if (opts.multipart || params instanceof FormData) {

@@ -191,3 +188,3 @@ return params;

}
exports.formatBody = formatBody;
function maybeAddMy(url) {

@@ -198,3 +195,3 @@ var myHost = config.getMyHost();

}
if (!(0, _url.isAbsolute)(url)) {
if (!(0, url_1.isAbsolute)(url)) {
return config.getMyHost() + url;

@@ -204,19 +201,21 @@ }

}
exports.maybeAddMy = maybeAddMy;
function isJSONResp(response) {
var contentType = response.headers.get('content-type');
return contentType && contentType.includes('application/json');
return Boolean(contentType && contentType.includes('application/json'));
}
function fetchDebugInfo(url, response) {
if (process.env.NODE_ENV !== 'production') {
if (!response.headers.has('x-debug-key')) return;
if (!window.CustomEvent) return;
if (!response.headers.has('x-debug-key'))
return;
if (!window.CustomEvent)
return;
var debugKey = response.headers.get('x-debug-key');
try {
var event = new CustomEvent('debug-toolbar-new-xhr', {
detail: { url: url, debugKey: debugKey, label: 'fio' }
var event_1 = new CustomEvent('debug-toolbar-new-xhr', {
detail: { url: url, debugKey: debugKey, label: 'fio' },
});
window.dispatchEvent(event);
} catch (err) {
window.dispatchEvent(event_1);
}
catch (err) {
console.warn(err);

@@ -226,73 +225,75 @@ }

}
function fetchJSON(url, info) {
return __awaiter(this, void 0, void 0, function () {
var response, data;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, fetch(url, info)];
case 1:
response = _a.sent();
if (!isOkResponse(response) && !isJSONResp(response)) {
throw new errors_1.FetchError('FetchNetworkError', "Bad status " + response.status + " '" + response.statusText + "'", null, response);
}
if (response.status === 204) { // 204 response cannot contain a message body
fetchDebugInfo(url, response);
return [2 /*return*/, null];
}
return [4 /*yield*/, response.json()];
case 2:
data = _a.sent();
// Check must throw an error if fails
checkResponseStatus(data, response);
checkDataStatus(data, response);
fetchDebugInfo(url, response);
return [2 /*return*/, data];
}
});
});
}
exports.fetchJSON = fetchJSON;
function unsafeMethodFactory(method) {
var _this = this;
return function () {
var _ref2 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(url, params) {
var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var user, options;
return regeneratorRuntime.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
if (!config.getSouldFetchPromUser()) {
_context2.next = 6;
break;
}
_context2.next = 3;
return (0, _userInfo.getUserInfo)();
case 3:
_context2.t0 = _context2.sent;
_context2.next = 7;
break;
case 6:
_context2.t0 = {};
case 7:
user = _context2.t0;
options = applyOpts(getDefaultOptions(method), opts);
if (CSRF_TOKEN_HEADER in options.headers) {
_context2.next = 13;
break;
}
_context2.next = 12;
return (0, _userInfo.getMyCSRF)();
case 12:
options.headers[CSRF_TOKEN_HEADER] = _context2.sent;
case 13:
user.id && (options.headers[PROMUSER_HEADER] = user.id);
options.body = formatBody(params, opts);
return _context2.abrupt('return', fetchJSON(url, options));
case 16:
case 'end':
return _context2.stop();
}
return function (url, params, opts) {
if (opts === void 0) { opts = {}; }
return __awaiter(_this, void 0, void 0, function () {
var user, _a, options, _b, _c;
return __generator(this, function (_d) {
switch (_d.label) {
case 0:
if (!config.getSouldFetchPromUser()) return [3 /*break*/, 2];
return [4 /*yield*/, (0, user_info_1.getUserInfo)()];
case 1:
_a = _d.sent();
return [3 /*break*/, 3];
case 2:
_a = null;
_d.label = 3;
case 3:
user = _a;
options = applyOpts(getDefaultOptions(method), opts);
if (!!(CSRF_TOKEN_HEADER in options.headers)) return [3 /*break*/, 5];
_b = options.headers;
_c = CSRF_TOKEN_HEADER;
return [4 /*yield*/, (0, user_info_1.getMyCSRF)()];
case 4:
_b[_c] = _d.sent();
_d.label = 5;
case 5:
(user === null || user === void 0 ? void 0 : user.id) && (options.headers[PROMUSER_HEADER] = user.id);
options.body = formatBody(params, opts);
return [2 /*return*/, fetchJSON(url, options)];
}
}, _callee2, _this);
}));
return function (_x5, _x6) {
return _ref2.apply(this, arguments);
};
}();
});
});
};
}
var makeMy = exports.makeMy = function makeMy(methodFunc) {
return function (rawUrl) {
for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
args[_key2 - 1] = arguments[_key2];
}
var url = maybeAddMy(rawUrl);
return methodFunc.apply(undefined, [url].concat(args));
};
};
exports.unsafeMethodFactory = unsafeMethodFactory;
var makeMy = function (methodFunc) { return function (rawUrl) {
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
var url = maybeAddMy(rawUrl);
return methodFunc.apply(void 0, __spreadArray([url], __read(args), false));
}; };
exports.makeMy = makeMy;
{
"name": "@evo/fetch-io",
"version": "2.3.1",
"version": "3.0.0",
"description": "",

@@ -12,3 +12,3 @@ "repository": {

"test": "jest",
"build": "babel src/ -d dist",
"build": "tsc",
"lint": "eslint src/",

@@ -20,21 +20,19 @@ "fix": "eslint --fix src/"

"devDependencies": {
"fetch-mock": "^6.0.0",
"@babel/preset-env": "7.16.4",
"@babel/preset-typescript": "7.16.0",
"@evo/prom-utils": "^0.2.6",
"@evo/user-info": "3.0.1",
"@types/jest": "^27.0.3",
"@types/js-cookie": "^3.0.1",
"fetch-mock": "9.11.0",
"js-cookie": "^3.0.1",
"ts-jest": "27.0.7",
"node-fetch": "^1.7.3",
"whatwg-fetch": "^2.0.3",
"@evo/prom-utils": "^0.2.6",
"@evo/user-info": "2.0.5"
"typescript": "4.4.4",
"whatwg-fetch": "3.6.2"
},
"peerDependencies": {
"whatwg-fetch": "^2.0.3",
"@evo/prom-utils": "^0.2.6",
"@evo/user-info": "^2.0.5"
},
"jest": {
"verbose": true,
"testURL": "http://localhost/",
"testMatch": [
"**/src/__tests__/**/*.js"
]
"@evo/user-info": "3.0.1",
"whatwg-fetch": "3.6.2"
}
}
{
"presets": ["env"]
}
'use strict';
var _userInfo = require('@evo/user-info');
var _jsCookie = require('js-cookie');
var _jsCookie2 = _interopRequireDefault(_jsCookie);
var _fetchMock = require('fetch-mock');
var _fetchMock2 = _interopRequireDefault(_fetchMock);
var _index = require('../index');
var _errors = require('../errors');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
var myOrigin = 'http://my.example.com:5000';
describe('fetch-io DELETE', function () {
var csrfToken = '1111';
var promUserId = 'testId';
var respWithParams = { params: 'test2' };
var respFromMy = { my: true };
beforeAll(function () {
(0, _index.init)(myOrigin);
(0, _userInfo.init)(myOrigin);
_jsCookie2.default.set('csrf_token', csrfToken);
_fetchMock2.default.delete('http://my.example.com:5000/test1_delete', respFromMy);
_fetchMock2.default.delete('/test1_delete', respWithParams);
_fetchMock2.default.delete('/test3', respWithParams);
_fetchMock2.default.delete('/status204_delete', 204);
_fetchMock2.default.delete('/status500_delete', 500);
_fetchMock2.default.delete('/error_data_status_delete', { body: { status: 'error' } });
_fetchMock2.default.delete('/error_data_status_error_delete', {
status: 500,
body: { status: 'error' },
headers: {
'content-type': 'application/json'
}
});
});
afterAll(function () {
_fetchMock2.default.restore();
});
it('should delete to url', function (done) {
(0, _userInfo.init)(myOrigin, { id: promUserId });
(0, _index.DELETE)('/test1_delete', respWithParams).then(function (data) {
expect(data).toEqual(respWithParams);
(0, _userInfo.init)(myOrigin, undefined);
done();
});
});
it('should set credentials include for CORS', function () {
var fetchOpts = _fetchMock2.default.lastOptions('/test1_delete');
expect(Object.keys(fetchOpts)).toContain('credentials');
expect(fetchOpts.credentials).toEqual('include');
});
it('should overwrite default fetch info', _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
var fetchOpts;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return (0, _index.DELETE)('/test3', {}, { credentials: 'same-origin' });
case 2:
fetchOpts = _fetchMock2.default.lastOptions('/test3');
expect(fetchOpts).toHaveProperty('credentials');
expect(fetchOpts.credentials).toEqual('same-origin');
case 5:
case 'end':
return _context.stop();
}
}
}, _callee, undefined);
})));
it('should include default content-type application/json; charset=UTF-8', function () {
var fetchOpts = _fetchMock2.default.lastOptions('/test1_delete');
expect(Object.keys(fetchOpts)).toContain('headers');
expect(Object.keys(fetchOpts.headers)).toContain('Content-Type');
expect(fetchOpts.headers['Content-Type']).toEqual('application/json; charset=UTF-8');
});
it('should include csrf tocken', function () {
var fetchOpts = _fetchMock2.default.lastOptions('/test1_delete');
expect(Object.keys(fetchOpts)).toContain('headers');
expect(Object.keys(fetchOpts.headers)).toContain('X-CSRFToken');
expect(fetchOpts.headers['X-CSRFToken']).toEqual(csrfToken);
});
it('should include X-Requested-With header', function () {
var fetchOpts = _fetchMock2.default.lastOptions('/test1_delete');
expect(Object.keys(fetchOpts)).toContain('headers');
expect(Object.keys(fetchOpts.headers)).toContain('X-Requested-With');
expect(fetchOpts.headers['X-Requested-With']).toEqual('XMLHttpRequest');
});
it('should include prom user id', function () {
var fetchOpts = _fetchMock2.default.lastOptions('/test1_delete');
expect(fetchOpts).toHaveProperty('headers');
expect(fetchOpts.headers).toHaveProperty('X-PromUserID');
expect(fetchOpts.headers['X-PromUserID']).toEqual(promUserId);
});
it('should reject if 500 status', function (done) {
(0, _index.DELETE)('/status500_delete', respWithParams).then(function (data) {
expect(data).toEqual(respWithParams);
}).catch(function (err) {
expect(err).toBeInstanceOf(_errors.FetchNetworkError);
expect(err.response.status).toEqual(500);
done();
});
});
it('should reject if data.status is error', function (done) {
(0, _index.DELETE)('/error_data_status_delete').catch(function (err) {
expect(err).toBeInstanceOf(_errors.FetchDataError);
expect(err.data).toEqual({ status: 'error' });
done();
});
});
it('should not fail if body is a dumped json string', function (done) {
(0, _index.DELETE)('/test1_delete', JSON.stringify(respWithParams)).then(function (data) {
var calledWith = _fetchMock2.default.lastCall('/test1_delete');
expect(data).toEqual(respWithParams);
expect(calledWith[1].body).toEqual('{"params":"test2"}');
done();
});
});
it('should apply "my" domain to the relative path', function (done) {
_index.my.DELETE('/test1_delete').then(function (data) {
expect(data).toEqual(respFromMy);
done();
});
});
it('should parse error data if it has json content type', function (done) {
(0, _index.DELETE)('/error_data_status_error_delete').catch(function (err) {
expect(err).toBeInstanceOf(_errors.FetchNetworkError);
expect(err.data).toEqual({ status: 'error' });
done();
});
});
it('should return null if 204 status', function (done) {
(0, _index.DELETE)('/status204_delete').then(function (data) {
expect(data).toEqual(null);
done();
});
});
});
'use strict';
var _userInfo = require('@evo/user-info');
var _fetchMock = require('fetch-mock');
var _fetchMock2 = _interopRequireDefault(_fetchMock);
var _index = require('../index');
var _errors = require('../errors');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
var myOrigin = 'http://my.example.com:5000';
describe('fetch-io GET', function () {
var respWithNoParams = { params: 'test1' };
var respWithParams = { params: 'test2' };
var respFromMy = { my: true };
beforeAll(function () {
(0, _index.init)(myOrigin);
(0, _userInfo.init)(myOrigin);
_fetchMock2.default.get('http://my.example.com:5000/test1', respFromMy);
_fetchMock2.default.get('/test1', respWithNoParams);
_fetchMock2.default.get('/test2?param1=1&param2=2', respWithParams);
_fetchMock2.default.get('/test3', respWithNoParams);
_fetchMock2.default.get('/status204', 204);
_fetchMock2.default.get('/status500', 500);
_fetchMock2.default.get('/error_data_status', { body: { status: 'error' } });
_fetchMock2.default.get('/error_data_status_error_get', {
status: 500,
body: { status: 'error' },
headers: {
'content-type': 'application/json'
}
});
});
afterAll(function () {
_fetchMock2.default.restore();
});
it('should execute GET request with no params', function (done) {
(0, _index.GET)('/test1', {}, { headers: { 'X-Custom-Header': 'custom' } }).then(function (data) {
expect(data).toEqual(respWithNoParams);
done();
});
});
it('should set credentials include for CORS and default headers', function () {
var fetchOpts = _fetchMock2.default.lastOptions('/test1');
expect(fetchOpts).toHaveProperty('credentials');
expect(fetchOpts.credentials).toEqual('include');
});
it('should include X-Requested-With header', function () {
var fetchOpts = _fetchMock2.default.lastOptions('/test1');
expect(fetchOpts.headers).toHaveProperty('X-Requested-With');
expect(fetchOpts.headers['X-Requested-With']).toEqual('XMLHttpRequest');
});
it('should include custom header', function () {
var fetchOpts = _fetchMock2.default.lastOptions('/test1');
expect(fetchOpts.headers).toHaveProperty('X-Custom-Header');
expect(fetchOpts.headers['X-Custom-Header']).toEqual('custom');
});
it('should overwrite default fetch info', _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
var fetchOpts;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return (0, _index.GET)('/test3', {}, { credentials: 'same-origin' });
case 2:
fetchOpts = _fetchMock2.default.lastOptions('/test3');
expect(fetchOpts).toHaveProperty('credentials');
expect(fetchOpts.credentials).toEqual('same-origin');
case 5:
case 'end':
return _context.stop();
}
}
}, _callee, undefined);
})));
it('should include default content-type application/json; charset=UTF-8', function () {
var fetchOpts = _fetchMock2.default.lastOptions('/test1');
expect(fetchOpts).toHaveProperty('headers');
expect(fetchOpts.headers).toHaveProperty('Content-Type');
expect(fetchOpts.headers['Content-Type']).toEqual('application/json; charset=UTF-8');
});
it('should include X-Requested-With header', function () {
var fetchOpts = _fetchMock2.default.lastOptions('/test1');
expect(fetchOpts).toHaveProperty('headers');
expect(fetchOpts.headers).toHaveProperty('X-Requested-With');
expect(fetchOpts.headers['X-Requested-With']).toEqual('XMLHttpRequest');
});
it('should execute GET request with params', function (done) {
(0, _index.GET)('/test2', { param1: 1, param2: 2 }).then(function (data) {
expect(data).toEqual(respWithParams);
done();
});
});
it('should reject if 500 status', function (done) {
(0, _index.GET)('/status500').then(function (data) {
expect(data).toEqual(respWithNoParams);
}).catch(function (err) {
expect(err).toBeInstanceOf(_errors.FetchNetworkError);
expect(err.response.status).toEqual(500);
done();
});
});
it('should reject if data.status is error', function (done) {
(0, _index.GET)('/error_data_status').catch(function (err) {
expect(err).toBeInstanceOf(_errors.FetchDataError);
expect(err.data).toEqual({ status: 'error' });
done();
});
});
it('should apply "my" domain to the relative path', function (done) {
_index.my.GET('/test1').then(function (data) {
expect(data).toEqual(respFromMy);
done();
});
});
it('should parse error data if it has json content type', function (done) {
(0, _index.GET)('/error_data_status_error_get').catch(function (err) {
expect(err).toBeInstanceOf(_errors.FetchNetworkError);
expect(err.data).toEqual({ status: 'error' });
done();
});
});
it('should return null if 204 status', function (done) {
(0, _index.GET)('/status204').then(function (data) {
expect(data).toEqual(null);
done();
});
});
});
'use strict';
var _userInfo = require('@evo/user-info');
var _fetchMock = require('fetch-mock');
var _fetchMock2 = _interopRequireDefault(_fetchMock);
var _jsCookie = require('js-cookie');
var _jsCookie2 = _interopRequireDefault(_jsCookie);
var _index = require('../index');
var _errors = require('../errors');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } /* eslint-disable max-nested-callbacks */
var myOrigin = 'http://my.example.com:5000';
describe('fetch-io POST', function () {
var csrfToken = '1111';
var promUserId = 'testId';
var respWithParams = { params: 'test2' };
var respFromMy = { my: true };
beforeAll(function () {
(0, _index.init)(myOrigin);
(0, _userInfo.init)(myOrigin);
_jsCookie2.default.set('csrf_token', csrfToken);
_fetchMock2.default.post('http://my.example.com:5000/test1_post', respFromMy);
_fetchMock2.default.post('/test1_post', respWithParams);
_fetchMock2.default.post('/test3', respWithParams);
_fetchMock2.default.post('/status204_post', 204);
_fetchMock2.default.post('/status500_post', 500);
_fetchMock2.default.post('/error_data_status_post', { body: { status: 'error' } });
_fetchMock2.default.post('/error_data_status_error_post', {
status: 500,
body: { status: 'error' },
headers: {
'content-type': 'application/json'
}
});
});
afterAll(function () {
_fetchMock2.default.restore();
});
it('should post to url', function (done) {
(0, _userInfo.init)(myOrigin, { id: promUserId });
(0, _index.POST)('/test1_post', respWithParams).then(function (data) {
expect(data).toEqual(respWithParams);
(0, _userInfo.init)(myOrigin, { id: promUserId });
done();
});
});
it('should set credentials include for CORS', function () {
var fetchOpts = _fetchMock2.default.lastOptions('/test1_post');
expect(fetchOpts).toHaveProperty('credentials');
expect(fetchOpts.credentials).toEqual('include');
});
it('should overwrite default fetch info', _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
var fetchOpts;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return (0, _index.POST)('/test3', {}, { credentials: 'same-origin' });
case 2:
fetchOpts = _fetchMock2.default.lastOptions('/test3');
expect(fetchOpts).toHaveProperty('credentials');
expect(fetchOpts.credentials).toEqual('same-origin');
case 5:
case 'end':
return _context.stop();
}
}
}, _callee, undefined);
})));
it('should include default content-type application/json; charset=UTF-8', function () {
var fetchOpts = _fetchMock2.default.lastOptions('/test1_post');
expect(fetchOpts).toHaveProperty('headers');
expect(fetchOpts.headers).toHaveProperty('Content-Type');
expect(fetchOpts.headers['Content-Type']).toEqual('application/json; charset=UTF-8');
});
it('should include csrf tocken', function () {
var fetchOpts = _fetchMock2.default.lastOptions('/test1_post');
expect(fetchOpts).toHaveProperty('headers');
expect(fetchOpts.headers).toHaveProperty('X-CSRFToken');
expect(fetchOpts.headers['X-CSRFToken']).toEqual(csrfToken);
});
it('should include X-Requested-With header', function () {
var fetchOpts = _fetchMock2.default.lastOptions('/test1_post');
expect(fetchOpts).toHaveProperty('headers');
expect(fetchOpts.headers).toHaveProperty('X-Requested-With');
expect(fetchOpts.headers['X-Requested-With']).toEqual('XMLHttpRequest');
});
it('should include prom user id', function () {
var fetchOpts = _fetchMock2.default.lastOptions('/test1_post');
expect(fetchOpts).toHaveProperty('headers');
expect(fetchOpts.headers).toHaveProperty('X-PromUserID');
expect(fetchOpts.headers['X-PromUserID']).toEqual(promUserId);
});
it('should reject if 500 status', function (done) {
(0, _index.POST)('/status500_post', respWithParams).then(function (data) {
expect(data).toEqual(respWithParams);
}).catch(function (err) {
expect(err).toBeInstanceOf(_errors.FetchNetworkError);
expect(err.response.status).toEqual(500);
done();
});
});
it('should reject if data.status is error', function (done) {
(0, _index.POST)('/error_data_status_post').catch(function (err) {
expect(err).toBeInstanceOf(_errors.FetchDataError);
expect(err.data).toEqual({ status: 'error' });
done();
});
});
it('should not fail if body is a dumped json string', function (done) {
(0, _index.POST)('/test1_post', JSON.stringify(respWithParams)).then(function (data) {
var calledWith = _fetchMock2.default.lastCall('/test1_post');
expect(data).toEqual(respWithParams);
expect(calledWith[1].body).toEqual('{"params":"test2"}');
done();
});
});
it('should delete content-type for multipart requests', function (done) {
(0, _index.POST)('/test1_post', {}, { multipart: true }).then(function () {
var calledWith = _fetchMock2.default.lastCall('/test1_post');
var requestHeaders = Object.keys(calledWith[1].headers)
// eslint-disable-next max-nested-callbacks
.map(function (x) {
return x.toLowerCase();
});
expect(requestHeaders).not.toHaveProperty('content-type');
done();
});
});
it('should pass request body for multipart requests as is', function (done) {
(0, _index.POST)('/test1_post', new window.FormData(), { multipart: true }).then(function () {
var calledWith = _fetchMock2.default.lastCall('/test1_post');
expect(calledWith[1].body).toBeInstanceOf(window.FormData);
done();
});
});
it('should apply "my" domain to the relative path', function (done) {
_index.my.POST('/test1_post').then(function (data) {
expect(data).toEqual(respFromMy);
done();
});
});
it('should pass FormData to init as is', function (done) {
(0, _index.POST)('/test1_post', new window.FormData()).then(function () {
var calledWith = _fetchMock2.default.lastCall('/test1_post');
expect(calledWith[1].body).toBeInstanceOf(window.FormData);
done();
});
});
it('should process custom opts', function (done) {
var params = { kek: 'param' };
var opts = {
referrer: 'no-referrer',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
};
(0, _index.POST)('/test1_post', params, opts).then(function () {
var calledWith = _fetchMock2.default.lastCall('/test1_post');
expect(calledWith[1].referrer).toEqual('no-referrer');
expect(calledWith[1].headers['Content-Type']).toEqual('application/x-www-form-urlencoded');
done();
});
});
it('should parse error data if it has json content type', function (done) {
var params = { kek: 'param' };
(0, _index.POST)('/error_data_status_error_post', params).catch(function (err) {
expect(err).toBeInstanceOf(_errors.FetchNetworkError);
expect(err.data).toEqual({ status: 'error' });
done();
});
});
it('should return null if 204 status', function (done) {
(0, _index.POST)('/status204_post').then(function (data) {
expect(data).toEqual(null);
done();
});
});
});
'use strict';
var _userInfo = require('@evo/user-info');
var _fetchMock = require('fetch-mock');
var _fetchMock2 = _interopRequireDefault(_fetchMock);
var _jsCookie = require('js-cookie');
var _jsCookie2 = _interopRequireDefault(_jsCookie);
var _index = require('../index');
var _errors = require('../errors');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
var myOrigin = 'http://my.example.com:5000';
describe('fetch-io PUT', function () {
var csrfToken = '1111';
var promUserId = 'testId';
var respWithParams = { params: 'test2' };
var respFromMy = { my: true };
beforeAll(function () {
(0, _index.init)(myOrigin);
(0, _userInfo.init)(myOrigin);
_jsCookie2.default.set('csrf_token', csrfToken);
_fetchMock2.default.put('http://my.example.com:5000/test1_put', respFromMy);
_fetchMock2.default.put('/test1_put', respWithParams);
_fetchMock2.default.put('/test3', respWithParams);
_fetchMock2.default.put('/status204_put', 204);
_fetchMock2.default.put('/status500_put', 500);
_fetchMock2.default.put('/error_data_status_put', { body: { status: 'error' } });
_fetchMock2.default.put('/error_data_status_error_put', {
status: 500,
body: { status: 'error' },
headers: {
'content-type': 'application/json'
}
});
});
afterAll(function () {
_fetchMock2.default.restore();
});
it('should put to url', function (done) {
(0, _userInfo.init)(myOrigin, { id: promUserId });
(0, _index.PUT)('/test1_put', respWithParams).then(function (data) {
expect(data).toEqual(respWithParams);
(0, _userInfo.init)(myOrigin, undefined);
done();
});
});
it('should set credentials include for CORS', function () {
var fetchOpts = _fetchMock2.default.lastOptions('/test1_put');
expect(fetchOpts).toHaveProperty('credentials');
expect(fetchOpts.credentials).toEqual('include');
});
it('should overwrite default fetch info', _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
var fetchOpts;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return (0, _index.PUT)('/test3', {}, { credentials: 'same-origin' });
case 2:
fetchOpts = _fetchMock2.default.lastOptions('/test3');
expect(fetchOpts).toHaveProperty('credentials');
expect(fetchOpts.credentials).toEqual('same-origin');
case 5:
case 'end':
return _context.stop();
}
}
}, _callee, undefined);
})));
it('should include default content-type application/json; charset=UTF-8', function () {
var fetchOpts = _fetchMock2.default.lastOptions('/test1_put');
expect(fetchOpts).toHaveProperty('headers');
expect(fetchOpts.headers).toHaveProperty('Content-Type');
expect(fetchOpts.headers['Content-Type']).toEqual('application/json; charset=UTF-8');
});
it('should include csrf tocken', function () {
var fetchOpts = _fetchMock2.default.lastOptions('/test1_put');
expect(fetchOpts).toHaveProperty('headers');
expect(fetchOpts.headers).toHaveProperty('X-CSRFToken');
expect(fetchOpts.headers['X-CSRFToken']).toEqual(csrfToken);
});
it('should include X-Requested-With header', function () {
var fetchOpts = _fetchMock2.default.lastOptions('/test1_put');
expect(fetchOpts).toHaveProperty('headers');
expect(fetchOpts.headers).toHaveProperty('X-Requested-With');
expect(fetchOpts.headers['X-Requested-With']).toEqual('XMLHttpRequest');
});
it('should include prom user id', function () {
var fetchOpts = _fetchMock2.default.lastOptions('/test1_put');
expect(fetchOpts).toHaveProperty('headers');
expect(fetchOpts.headers).toHaveProperty('X-PromUserID');
expect(fetchOpts.headers['X-PromUserID']).toEqual(promUserId);
});
it('should reject if 500 status', function (done) {
(0, _index.PUT)('/status500_put', respWithParams).then(function (data) {
expect(data).toEqual(respWithParams);
}).catch(function (err) {
expect(err).toBeInstanceOf(_errors.FetchNetworkError);
expect(err.response.status).toEqual(500);
done();
});
});
it('should reject if data.status is error', function (done) {
(0, _index.PUT)('/error_data_status_put').catch(function (err) {
expect(err).toBeInstanceOf(_errors.FetchDataError);
expect(err.data).toEqual({ status: 'error' });
done();
});
});
it('should not fail if body is a dumped json string', function (done) {
(0, _index.PUT)('/test1_put', JSON.stringify(respWithParams)).then(function (data) {
var calledWith = _fetchMock2.default.lastCall('/test1_put');
expect(data).toEqual(respWithParams);
expect(calledWith[1].body).toEqual('{"params":"test2"}');
done();
});
});
it('should apply "my" domain to the relative path', function (done) {
_index.my.PUT('/test1_put').then(function (data) {
expect(data).toEqual(respFromMy);
done();
});
});
it('should parse error data if it has json content type', function (done) {
var params = { kek: 'param' };
(0, _index.PUT)('/error_data_status_error_put', params).catch(function (err) {
expect(err).toBeInstanceOf(_errors.FetchNetworkError);
expect(err.data).toEqual({ status: 'error' });
done();
});
});
it('should return null if 204 status', function (done) {
(0, _index.PUT)('/status204_put').then(function (data) {
expect(data).toEqual(null);
done();
});
});
});
import { init as initUserInfo } from '@evo/user-info';
import cookie from 'js-cookie';
import fetchMock from 'fetch-mock';
import { DELETE, my, init } from '../index';
import { FetchNetworkError, FetchDataError } from '../errors';
const myOrigin = 'http://my.example.com:5000';
describe('fetch-io DELETE', () => {
const csrfToken = '1111';
const promUserId = 'testId';
const respWithParams = { params: 'test2' };
const respFromMy = { my: true };
beforeAll(() => {
init(myOrigin);
initUserInfo(myOrigin);
cookie.set('csrf_token', csrfToken);
fetchMock.delete('http://my.example.com:5000/test1_delete', respFromMy);
fetchMock.delete('/test1_delete', respWithParams);
fetchMock.delete('/test3', respWithParams);
fetchMock.delete('/status204_delete', 204);
fetchMock.delete('/status500_delete', 500);
fetchMock.delete('/error_data_status_delete', { body: { status: 'error' } });
fetchMock.delete('/error_data_status_error_delete',
{
status: 500,
body: { status: 'error' },
headers: {
'content-type': 'application/json'
}
});
});
afterAll(() => {
fetchMock.restore();
});
it('should delete to url', (done) => {
initUserInfo(myOrigin, { id: promUserId });
DELETE('/test1_delete', respWithParams).then((data) => {
expect(data).toEqual(respWithParams);
initUserInfo(myOrigin, undefined);
done();
});
});
it('should set credentials include for CORS', () => {
const fetchOpts = fetchMock.lastOptions('/test1_delete');
expect(Object.keys(fetchOpts)).toContain('credentials');
expect(fetchOpts.credentials).toEqual('include');
});
it('should overwrite default fetch info', async () => {
await DELETE('/test3', {}, { credentials: 'same-origin' });
const fetchOpts = fetchMock.lastOptions('/test3');
expect(fetchOpts).toHaveProperty('credentials');
expect(fetchOpts.credentials).toEqual('same-origin');
});
it('should include default content-type application/json; charset=UTF-8', () => {
const fetchOpts = fetchMock.lastOptions('/test1_delete');
expect(Object.keys(fetchOpts)).toContain('headers');
expect(Object.keys(fetchOpts.headers)).toContain('Content-Type');
expect(fetchOpts.headers['Content-Type']).toEqual('application/json; charset=UTF-8');
});
it('should include csrf tocken', () => {
const fetchOpts = fetchMock.lastOptions('/test1_delete');
expect(Object.keys(fetchOpts)).toContain('headers');
expect(Object.keys(fetchOpts.headers)).toContain('X-CSRFToken');
expect(fetchOpts.headers['X-CSRFToken']).toEqual(csrfToken);
});
it('should include X-Requested-With header', () => {
const fetchOpts = fetchMock.lastOptions('/test1_delete');
expect(Object.keys(fetchOpts)).toContain('headers');
expect(Object.keys(fetchOpts.headers)).toContain('X-Requested-With');
expect(fetchOpts.headers['X-Requested-With']).toEqual('XMLHttpRequest');
});
it('should include prom user id', () => {
const fetchOpts = fetchMock.lastOptions('/test1_delete');
expect(fetchOpts).toHaveProperty('headers');
expect(fetchOpts.headers).toHaveProperty('X-PromUserID');
expect(fetchOpts.headers['X-PromUserID']).toEqual(promUserId);
});
it('should reject if 500 status', (done) => {
DELETE('/status500_delete', respWithParams).then((data) => {
expect(data).toEqual(respWithParams);
}).catch((err) => {
expect(err).toBeInstanceOf(FetchNetworkError);
expect(err.response.status).toEqual(500);
done();
});
});
it('should reject if data.status is error', (done) => {
DELETE('/error_data_status_delete').catch((err) => {
expect(err).toBeInstanceOf(FetchDataError);
expect(err.data).toEqual({ status: 'error' });
done();
});
});
it('should not fail if body is a dumped json string', (done) => {
DELETE('/test1_delete', JSON.stringify(respWithParams)).then((data) => {
const calledWith = fetchMock.lastCall('/test1_delete');
expect(data).toEqual(respWithParams);
expect(calledWith[1].body).toEqual('{"params":"test2"}');
done();
});
});
it('should apply "my" domain to the relative path', (done) => {
my.DELETE('/test1_delete').then((data) => {
expect(data).toEqual(respFromMy);
done();
});
});
it('should parse error data if it has json content type', (done) => {
DELETE('/error_data_status_error_delete')
.catch((err) => {
expect(err).toBeInstanceOf(FetchNetworkError);
expect(err.data).toEqual({ status: 'error' });
done();
});
});
it('should return null if 204 status', (done) => {
DELETE('/status204_delete')
.then((data) => {
expect(data).toEqual(null);
done();
});
});
});
import { init as initUserInfo } from '@evo/user-info';
import fetchMock from 'fetch-mock';
import { GET, my, init } from '../index';
import { FetchNetworkError, FetchDataError } from '../errors';
const myOrigin = 'http://my.example.com:5000';
describe('fetch-io GET', () => {
const respWithNoParams = { params: 'test1' };
const respWithParams = { params: 'test2' };
const respFromMy = { my: true };
beforeAll(() => {
init(myOrigin);
initUserInfo(myOrigin);
fetchMock.get('http://my.example.com:5000/test1', respFromMy);
fetchMock.get('/test1', respWithNoParams);
fetchMock.get('/test2?param1=1&param2=2', respWithParams);
fetchMock.get('/test3', respWithNoParams);
fetchMock.get('/status204', 204);
fetchMock.get('/status500', 500);
fetchMock.get('/error_data_status', { body: { status: 'error' } });
fetchMock.get('/error_data_status_error_get',
{
status: 500,
body: { status: 'error' },
headers: {
'content-type': 'application/json'
}
});
});
afterAll(() => {
fetchMock.restore();
});
it('should execute GET request with no params', (done) => {
GET('/test1',
{},
{ headers: { 'X-Custom-Header': 'custom' } }
).then((data) => {
expect(data).toEqual(respWithNoParams);
done();
});
});
it('should set credentials include for CORS and default headers', () => {
const fetchOpts = fetchMock.lastOptions('/test1');
expect(fetchOpts).toHaveProperty('credentials');
expect(fetchOpts.credentials).toEqual('include');
});
it('should include X-Requested-With header', () => {
const fetchOpts = fetchMock.lastOptions('/test1');
expect(fetchOpts.headers).toHaveProperty('X-Requested-With');
expect(fetchOpts.headers['X-Requested-With']).toEqual('XMLHttpRequest');
});
it('should include custom header', () => {
const fetchOpts = fetchMock.lastOptions('/test1');
expect(fetchOpts.headers).toHaveProperty('X-Custom-Header');
expect(fetchOpts.headers['X-Custom-Header']).toEqual('custom');
});
it('should overwrite default fetch info', async () => {
await GET('/test3', {}, { credentials: 'same-origin' });
const fetchOpts = fetchMock.lastOptions('/test3');
expect(fetchOpts).toHaveProperty('credentials');
expect(fetchOpts.credentials).toEqual('same-origin');
});
it('should include default content-type application/json; charset=UTF-8', () => {
const fetchOpts = fetchMock.lastOptions('/test1');
expect(fetchOpts).toHaveProperty('headers');
expect(fetchOpts.headers).toHaveProperty('Content-Type');
expect(fetchOpts.headers['Content-Type']).toEqual('application/json; charset=UTF-8');
});
it('should include X-Requested-With header', () => {
const fetchOpts = fetchMock.lastOptions('/test1');
expect(fetchOpts).toHaveProperty('headers');
expect(fetchOpts.headers).toHaveProperty('X-Requested-With');
expect(fetchOpts.headers['X-Requested-With']).toEqual('XMLHttpRequest');
});
it('should execute GET request with params', (done) => {
GET('/test2', { param1: 1, param2: 2 }).then((data) => {
expect(data).toEqual(respWithParams);
done();
});
});
it('should reject if 500 status', (done) => {
GET('/status500').then((data) => {
expect(data).toEqual(respWithNoParams);
}).catch((err) => {
expect(err).toBeInstanceOf(FetchNetworkError);
expect(err.response.status).toEqual(500);
done();
});
});
it('should reject if data.status is error', (done) => {
GET('/error_data_status').catch((err) => {
expect(err).toBeInstanceOf(FetchDataError);
expect(err.data).toEqual({ status: 'error' });
done();
});
});
it('should apply "my" domain to the relative path', (done) => {
my.GET('/test1').then((data) => {
expect(data).toEqual(respFromMy);
done();
});
});
it('should parse error data if it has json content type', (done) => {
GET('/error_data_status_error_get')
.catch((err) => {
expect(err).toBeInstanceOf(FetchNetworkError);
expect(err.data).toEqual({ status: 'error' });
done();
});
});
it('should return null if 204 status', (done) => {
GET('/status204')
.then((data) => {
expect(data).toEqual(null);
done();
});
});
});
/* eslint-disable max-nested-callbacks */
import { init as initUserInfo } from '@evo/user-info';
import fetchMock from 'fetch-mock';
import cookie from 'js-cookie';
import { POST, my, init } from '../index';
import { FetchNetworkError, FetchDataError } from '../errors';
const myOrigin = 'http://my.example.com:5000';
describe('fetch-io POST', () => {
const csrfToken = '1111';
const promUserId = 'testId';
const respWithParams = { params: 'test2' };
const respFromMy = { my: true };
beforeAll(() => {
init(myOrigin);
initUserInfo(myOrigin);
cookie.set('csrf_token', csrfToken);
fetchMock.post('http://my.example.com:5000/test1_post', respFromMy);
fetchMock.post('/test1_post', respWithParams);
fetchMock.post('/test3', respWithParams);
fetchMock.post('/status204_post', 204);
fetchMock.post('/status500_post', 500);
fetchMock.post('/error_data_status_post', { body: { status: 'error' } });
fetchMock.post('/error_data_status_error_post',
{
status: 500,
body: { status: 'error' },
headers: {
'content-type': 'application/json'
}
});
});
afterAll(() => {
fetchMock.restore();
});
it('should post to url', (done) => {
initUserInfo(myOrigin, { id: promUserId });
POST('/test1_post', respWithParams).then((data) => {
expect(data).toEqual(respWithParams);
initUserInfo(myOrigin, { id: promUserId });
done();
});
});
it('should set credentials include for CORS', () => {
const fetchOpts = fetchMock.lastOptions('/test1_post');
expect(fetchOpts).toHaveProperty('credentials');
expect(fetchOpts.credentials).toEqual('include');
});
it('should overwrite default fetch info', async () => {
await POST('/test3', {}, { credentials: 'same-origin' });
const fetchOpts = fetchMock.lastOptions('/test3');
expect(fetchOpts).toHaveProperty('credentials');
expect(fetchOpts.credentials).toEqual('same-origin');
});
it('should include default content-type application/json; charset=UTF-8', () => {
const fetchOpts = fetchMock.lastOptions('/test1_post');
expect(fetchOpts).toHaveProperty('headers');
expect(fetchOpts.headers).toHaveProperty('Content-Type');
expect(fetchOpts.headers['Content-Type']).toEqual('application/json; charset=UTF-8');
});
it('should include csrf tocken', () => {
const fetchOpts = fetchMock.lastOptions('/test1_post');
expect(fetchOpts).toHaveProperty('headers');
expect(fetchOpts.headers).toHaveProperty('X-CSRFToken');
expect(fetchOpts.headers['X-CSRFToken']).toEqual(csrfToken);
});
it('should include X-Requested-With header', () => {
const fetchOpts = fetchMock.lastOptions('/test1_post');
expect(fetchOpts).toHaveProperty('headers');
expect(fetchOpts.headers).toHaveProperty('X-Requested-With');
expect(fetchOpts.headers['X-Requested-With']).toEqual('XMLHttpRequest');
});
it('should include prom user id', () => {
const fetchOpts = fetchMock.lastOptions('/test1_post');
expect(fetchOpts).toHaveProperty('headers');
expect(fetchOpts.headers).toHaveProperty('X-PromUserID');
expect(fetchOpts.headers['X-PromUserID']).toEqual(promUserId);
});
it('should reject if 500 status', (done) => {
POST('/status500_post', respWithParams).then((data) => {
expect(data).toEqual(respWithParams);
}).catch((err) => {
expect(err).toBeInstanceOf(FetchNetworkError);
expect(err.response.status).toEqual(500);
done();
});
});
it('should reject if data.status is error', (done) => {
POST('/error_data_status_post').catch((err) => {
expect(err).toBeInstanceOf(FetchDataError);
expect(err.data).toEqual({ status: 'error' });
done();
});
});
it('should not fail if body is a dumped json string', (done) => {
POST('/test1_post', JSON.stringify(respWithParams)).then((data) => {
const calledWith = fetchMock.lastCall('/test1_post');
expect(data).toEqual(respWithParams);
expect(calledWith[1].body).toEqual('{"params":"test2"}');
done();
});
});
it('should delete content-type for multipart requests', (done) => {
POST('/test1_post', {}, { multipart: true }).then(() => {
const calledWith = fetchMock.lastCall('/test1_post');
const requestHeaders = Object.keys(calledWith[1].headers)
// eslint-disable-next max-nested-callbacks
.map((x) => x.toLowerCase());
expect(requestHeaders).not.toHaveProperty('content-type');
done();
});
});
it('should pass request body for multipart requests as is', (done) => {
POST('/test1_post', new window.FormData(), { multipart: true }).then(() => {
const calledWith = fetchMock.lastCall('/test1_post');
expect(calledWith[1].body).toBeInstanceOf(window.FormData);
done();
});
});
it('should apply "my" domain to the relative path', (done) => {
my.POST('/test1_post').then((data) => {
expect(data).toEqual(respFromMy);
done();
});
});
it('should pass FormData to init as is', (done) => {
POST('/test1_post', new window.FormData()).then(() => {
const calledWith = fetchMock.lastCall('/test1_post');
expect(calledWith[1].body).toBeInstanceOf(window.FormData);
done();
});
});
it('should process custom opts', (done) => {
const params = { kek: 'param' };
const opts = {
referrer: 'no-referrer',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
}
};
POST('/test1_post', params, opts).then(() => {
const calledWith = fetchMock.lastCall('/test1_post');
expect(calledWith[1].referrer).toEqual('no-referrer');
expect(calledWith[1].headers['Content-Type']).toEqual(
'application/x-www-form-urlencoded');
done();
});
});
it('should parse error data if it has json content type', (done) => {
const params = { kek: 'param' };
POST('/error_data_status_error_post', params)
.catch((err) => {
expect(err).toBeInstanceOf(FetchNetworkError);
expect(err.data).toEqual({ status: 'error' });
done();
});
});
it('should return null if 204 status', (done) => {
POST('/status204_post')
.then((data) => {
expect(data).toEqual(null);
done();
});
});
});
import { init as initUserInfo } from '@evo/user-info';
import fetchMock from 'fetch-mock';
import cookie from 'js-cookie';
import { PUT, my, init } from '../index';
import { FetchNetworkError, FetchDataError } from '../errors';
const myOrigin = 'http://my.example.com:5000';
describe('fetch-io PUT', () => {
const csrfToken = '1111';
const promUserId = 'testId';
const respWithParams = { params: 'test2' };
const respFromMy = { my: true };
beforeAll(() => {
init(myOrigin);
initUserInfo(myOrigin);
cookie.set('csrf_token', csrfToken);
fetchMock.put('http://my.example.com:5000/test1_put', respFromMy);
fetchMock.put('/test1_put', respWithParams);
fetchMock.put('/test3', respWithParams);
fetchMock.put('/status204_put', 204);
fetchMock.put('/status500_put', 500);
fetchMock.put('/error_data_status_put', { body: { status: 'error' } });
fetchMock.put('/error_data_status_error_put',
{
status: 500,
body: { status: 'error' },
headers: {
'content-type': 'application/json'
}
});
});
afterAll(() => {
fetchMock.restore();
});
it('should put to url', (done) => {
initUserInfo(myOrigin, { id: promUserId });
PUT('/test1_put', respWithParams).then((data) => {
expect(data).toEqual(respWithParams);
initUserInfo(myOrigin, undefined);
done();
});
});
it('should set credentials include for CORS', () => {
const fetchOpts = fetchMock.lastOptions('/test1_put');
expect(fetchOpts).toHaveProperty('credentials');
expect(fetchOpts.credentials).toEqual('include');
});
it('should overwrite default fetch info', async () => {
await PUT('/test3', {}, { credentials: 'same-origin' });
const fetchOpts = fetchMock.lastOptions('/test3');
expect(fetchOpts).toHaveProperty('credentials');
expect(fetchOpts.credentials).toEqual('same-origin');
});
it('should include default content-type application/json; charset=UTF-8', () => {
const fetchOpts = fetchMock.lastOptions('/test1_put');
expect(fetchOpts).toHaveProperty('headers');
expect(fetchOpts.headers).toHaveProperty('Content-Type');
expect(fetchOpts.headers['Content-Type']).toEqual('application/json; charset=UTF-8');
});
it('should include csrf tocken', () => {
const fetchOpts = fetchMock.lastOptions('/test1_put');
expect(fetchOpts).toHaveProperty('headers');
expect(fetchOpts.headers).toHaveProperty('X-CSRFToken');
expect(fetchOpts.headers['X-CSRFToken']).toEqual(csrfToken);
});
it('should include X-Requested-With header', () => {
const fetchOpts = fetchMock.lastOptions('/test1_put');
expect(fetchOpts).toHaveProperty('headers');
expect(fetchOpts.headers).toHaveProperty('X-Requested-With');
expect(fetchOpts.headers['X-Requested-With']).toEqual('XMLHttpRequest');
});
it('should include prom user id', () => {
const fetchOpts = fetchMock.lastOptions('/test1_put');
expect(fetchOpts).toHaveProperty('headers');
expect(fetchOpts.headers).toHaveProperty('X-PromUserID');
expect(fetchOpts.headers['X-PromUserID']).toEqual(promUserId);
});
it('should reject if 500 status', (done) => {
PUT('/status500_put', respWithParams).then((data) => {
expect(data).toEqual(respWithParams);
}).catch((err) => {
expect(err).toBeInstanceOf(FetchNetworkError);
expect(err.response.status).toEqual(500);
done();
});
});
it('should reject if data.status is error', (done) => {
PUT('/error_data_status_put').catch((err) => {
expect(err).toBeInstanceOf(FetchDataError);
expect(err.data).toEqual({ status: 'error' });
done();
});
});
it('should not fail if body is a dumped json string', (done) => {
PUT('/test1_put', JSON.stringify(respWithParams)).then((data) => {
const calledWith = fetchMock.lastCall('/test1_put');
expect(data).toEqual(respWithParams);
expect(calledWith[1].body).toEqual('{"params":"test2"}');
done();
});
});
it('should apply "my" domain to the relative path', (done) => {
my.PUT('/test1_put').then((data) => {
expect(data).toEqual(respFromMy);
done();
});
});
it('should parse error data if it has json content type', (done) => {
const params = { kek: 'param' };
PUT('/error_data_status_error_put', params)
.catch((err) => {
expect(err).toBeInstanceOf(FetchNetworkError);
expect(err.data).toEqual({ status: 'error' });
done();
});
});
it('should return null if 204 status', (done) => {
PUT('/status204_put')
.then((data) => {
expect(data).toEqual(null);
done();
});
});
});
let myHost = null;
let souldFetchPromUser = true;
export function getMyHost() {
return myHost;
}
export function setMyHost(host) {
myHost = host;
}
export function getSouldFetchPromUser() {
return souldFetchPromUser;
}
export function setSouldFetchPromUser(value) {
souldFetchPromUser = value;
}
export function FetchNetworkError(message, data, response) {
this.name = 'FetchNetworkError';
this.message = message;
this.response = response;
this.data = data;
}
FetchNetworkError.prototype = Object.create(Error.prototype);
FetchNetworkError.prototype.constructor = FetchNetworkError;
export function FetchDataError(message, data, response) {
this.name = 'FetchDataError';
this.message = message;
this.response = response;
this.data = data;
}
FetchDataError.prototype = Object.create(Error.prototype);
FetchDataError.prototype.constructor = FetchDataError;
import 'whatwg-fetch';
import { addGetParams } from '@evo/prom-utils/lib/url';
import { getDefaultOptions, unsafeMethodFactory, makeMy, fetchJSON, applyOpts } from './utils';
import * as config from './config';
/*
Example:
GET('/articles', { id: 123 })
.then((data) => console.log(data))
.catch((error) => console.error(error))
*/
export function GET(url, params, opts = {}) {
const urlWithParams = addGetParams(url, params);
const options = applyOpts(getDefaultOptions('GET'), opts);
return fetchJSON(urlWithParams, options);
}
/*
Example:
getJSON('/articles', { id: 123 })
.then((data) => console.log(data))
.catch((error) => console.error(error))
*/
export function getJSON(url, params) {
const urlWithParams = addGetParams(url, params);
return fetchJSON(urlWithParams, { method: 'GET' });
}
/*
Example:
POST('/articles', { id: 123 })
.then((data) => console.log(data))
.catch((error) => console.error(error))
*/
export const POST = unsafeMethodFactory('POST');
/*
Example:
PUT('/articles', { id: 123 })
.then((data) => console.log(data))
.catch((error) => console.error(error))
*/
export const PUT = unsafeMethodFactory('PUT');
/*
Example:
DELETE('/articles', { id: 123 })
.then((data) => console.log(data))
.catch((error) => console.error(error))
*/
export const DELETE = unsafeMethodFactory('DELETE');
/*
Wraps methods with function that will transform the first
argument (url) from relative path to absolute with my. domain
*/
export const my = {
GET: makeMy(GET),
getJSON: makeMy(getJSON),
POST: makeMy(POST),
PUT: makeMy(PUT),
DELETE: makeMy(DELETE),
};
export function init(host, userFetch = true) {
config.setMyHost(host);
config.setSouldFetchPromUser(userFetch);
}
import { isAbsolute } from '@evo/prom-utils/lib/url';
import { getMyCSRF, getUserInfo } from '@evo/user-info';
import { FetchNetworkError, FetchDataError } from './errors';
import * as config from './config';
const CSRF_TOKEN_HEADER = 'X-CSRFToken';
const PROMUSER_HEADER = 'X-PromUserID';
export function isObject(item) {
return (item && typeof item === 'object' && !Array.isArray(item));
}
const NAME = Symbol.toStringTag;
export const isAbortSignal = (object) => {
return (
typeof object === 'object' &&
(object[NAME] === 'AbortSignal' || object[NAME] === 'EventTarget')
);
};
export function mergeDeep(target, ...sources) {
if (!sources.length) return target;
const source = sources.shift();
if (isObject(target) && isObject(source)) {
Object.keys(source).forEach((key) => {
if (
isObject(source[key]) &&
(key !== 'signal' || !isAbortSignal(source[key]))
) {
if (!target[key]) Object.assign(target, { [key]: {} });
mergeDeep(target[key], source[key]);
} else {
Object.assign(target, { [key]: source[key] });
}
});
}
return target;
}
function isOkResponse(response) {
return response.status >= 200 && response.status < 300;
}
function isErrorDataStatus(data) {
return data && data.status && data.status === 'error';
}
export function checkResponseStatus(data, response) {
if (isOkResponse(response)) return response;
throw new FetchNetworkError(
`Bad status ${response.status} '${response.statusText}'`,
data, response);
}
export function checkDataStatus(data, response) {
if (!isErrorDataStatus(data)) return data;
throw new FetchDataError('Data error status', data, response);
}
export function parseJSON(resp) {
return resp.json();
}
function getDefaultHeaders() {
return {
Accept: 'application/json, text/plain, */*',
'Content-Type': 'application/json; charset=UTF-8',
'X-Requested-With': 'XMLHttpRequest' // need this for passing is_xhr check on a backend
};
}
export function getDefaultOptions(method) {
if (!method) {
throw Error('method is required!');
}
const defaultOptions = {
method,
credentials: 'include', // need this for CORS
headers: getDefaultHeaders(),
};
return defaultOptions;
}
export function applyOpts(options, opts = {}) {
options = mergeDeep(options, opts);
if (opts.multipart) {
delete options.headers['Content-Type'];
delete options.multipart;
}
return options;
}
export function formatBody(params, opts) {
if (opts.multipart || params instanceof FormData) {
return params;
}
return typeof params !== 'string' ? JSON.stringify(params) : params;
}
export function maybeAddMy(url) {
const myHost = config.getMyHost();
if (!myHost) {
throw new Error('You should set host to send the request to my domain');
}
if (!isAbsolute(url)) {
return config.getMyHost() + url;
}
return url;
}
function isJSONResp(response) {
const contentType = response.headers.get('content-type');
return contentType && contentType.includes('application/json');
}
function fetchDebugInfo(url, response) {
if (process.env.NODE_ENV !== 'production') {
if (!response.headers.has('x-debug-key')) return;
if (!window.CustomEvent) return;
const debugKey = response.headers.get('x-debug-key');
try {
const event = new CustomEvent('debug-toolbar-new-xhr', {
detail: { url, debugKey, label: 'fio' },
});
window.dispatchEvent(event);
} catch (err) {
console.warn(err);
}
}
}
export async function fetchJSON(url, info) {
const response = await fetch(url, info);
if (!isOkResponse(response) && !isJSONResp(response)) {
throw new FetchNetworkError(
`Bad status ${response.status} '${response.statusText}'`,
null,
response);
}
if (response.status === 204) { // 204 response cannot contain a message body
fetchDebugInfo(url, response);
return null;
}
const data = await response.json();
// Check must throw an error if fails
checkResponseStatus(data, response);
checkDataStatus(data, response);
fetchDebugInfo(url, response);
return data;
}
export function unsafeMethodFactory(method) {
return async (url, params, opts = {}) => {
const user = config.getSouldFetchPromUser() ? await getUserInfo() : {};
const options = applyOpts(getDefaultOptions(method), opts);
if (!(CSRF_TOKEN_HEADER in options.headers)) {
options.headers[CSRF_TOKEN_HEADER] = await getMyCSRF();
}
user.id && (options.headers[PROMUSER_HEADER] = user.id);
options.body = formatBody(params, opts);
return fetchJSON(url, options);
};
}
export const makeMy = (methodFunc) => (rawUrl, ...args) => {
const url = maybeAddMy(rawUrl);
return methodFunc(url, ...args);
};