@evo/fetch-io
Advanced tools
| module.exports = (api) => { | ||
| api.cache(false); | ||
| return { | ||
| presets: [ | ||
| ['@babel/preset-env', {targets: {node: 'current'}}], | ||
| '@babel/preset-typescript', | ||
| ], | ||
| } | ||
| } |
+11
| # 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; |
+95
| "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; |
+31
-26
@@ -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; |
+49
-50
@@ -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; |
+207
-206
@@ -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; |
+14
-16
| { | ||
| "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" | ||
| } | ||
| } |
-3
| { | ||
| "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¶m2=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¶m2=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; |
-68
| 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); | ||
| } |
-173
| 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); | ||
| }; |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
2
-33.33%1
-66.67%4
-85.71%29266
-61.24%12
100%16
-15.79%634
-62.6%