core-native
Version:
A lightweight framework based on React Native + Redux + Redux Saga, in strict TypeScript.
130 lines • 6.27 kB
JavaScript
/**
* Attention:
* Do NOT use "axios" for network utils in React Native.
*
* Explanation:
* 1) Axios supports [nodejs-http] and [XHR] only, does not support [fetch] API.
* 2) Although React Native has a XHR-same interface, but it has a bit difference on CORS policy.
* 3) If XHR is used in React Native (i.e, what axios does), customized response header cannot be retrieved.
*
* Ref:
* https://stackoverflow.com/questions/37897523/axios-get-access-to-response-header-fields
*/
import { __awaiter, __generator, __read } from "tslib";
import { APIException, NetworkConnectionException } from "../Exception";
import { parseWithDate } from "./json-util";
var networkInterceptor = {};
export function setRequestHeaderInterceptor(_) {
networkInterceptor.request = _;
}
export function setResponseHeaderInterceptor(_) {
networkInterceptor.response = _;
}
export function ajax(method, path, pathParams, request, skipInterceptor) {
var _a, _b;
if (skipInterceptor === void 0) { skipInterceptor = false; }
return __awaiter(this, void 0, void 0, function () {
var requestURL, requestHeaders, requestParameters, response, responseText, responseData, apiErrorResponse, errorId, errorCode, errorMessage, e_1;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
requestURL = urlParams(path, pathParams);
requestHeaders = new Headers({
"Content-Type": "application/json",
Accept: "application/json",
});
if (!!skipInterceptor) return [3 /*break*/, 2];
return [4 /*yield*/, ((_a = networkInterceptor.request) === null || _a === void 0 ? void 0 : _a.call(networkInterceptor, requestHeaders))];
case 1:
_c.sent();
_c.label = 2;
case 2:
requestParameters = { method: method, headers: requestHeaders };
if (request) {
if (method === "GET" || method === "DELETE") {
requestURL += queryString(request);
}
else {
requestParameters.body = JSON.stringify(request);
}
}
_c.label = 3;
case 3:
_c.trys.push([3, 8, , 9]);
return [4 /*yield*/, fetch(requestURL, requestParameters)];
case 4:
response = _c.sent();
if (!!skipInterceptor) return [3 /*break*/, 6];
return [4 /*yield*/, ((_b = networkInterceptor.response) === null || _b === void 0 ? void 0 : _b.call(networkInterceptor, response.headers))];
case 5:
_c.sent();
_c.label = 6;
case 6: return [4 /*yield*/, response.text()];
case 7:
responseText = _c.sent();
responseData = responseText ? parseWithDate(responseText) : {};
if (response.ok) {
// HTTP Status 200
return [2 /*return*/, responseData];
}
else {
apiErrorResponse = responseData;
errorId = (apiErrorResponse === null || apiErrorResponse === void 0 ? void 0 : apiErrorResponse.id) || null;
errorCode = (apiErrorResponse === null || apiErrorResponse === void 0 ? void 0 : apiErrorResponse.errorCode) || null;
if (!errorId && (response.status === 502 || response.status === 504)) {
// Treat "cloud" error as Network Exception, e.g: gateway issue, load balancer unconnected to application server
// Note: Status 503 is maintenance
throw new NetworkConnectionException("Gateway error (".concat(response.status, ")"), requestURL);
}
else {
errorMessage = responseData && responseData.message ? responseData.message : "[No Response]";
throw new APIException(errorMessage, response.status, requestURL, responseData, errorId, errorCode);
}
}
return [3 /*break*/, 9];
case 8:
e_1 = _c.sent();
// Only APIException, NetworkConnectionException can be thrown
if (e_1 instanceof APIException || e_1 instanceof NetworkConnectionException) {
throw e_1;
}
else {
throw new NetworkConnectionException("Failed to connect: ".concat(requestURL), requestURL, e_1 instanceof Error ? e_1.message : "[Unknown]");
}
return [3 /*break*/, 9];
case 9: return [2 /*return*/];
}
});
});
}
export function uri(path, request) {
return path + queryString(request);
}
export function urlParams(path, params) {
var pathWithParams = path;
Object.entries(params).forEach(function (_a) {
var _b = __read(_a, 2), name = _b[0], value = _b[1];
var encodedValue = encodeURIComponent(value.toString());
pathWithParams = pathWithParams.replace(":" + name, encodedValue);
});
return pathWithParams;
}
export function queryString(params) {
if (!params) {
return "";
}
var entries = Object.entries(params);
if (entries.length === 0) {
return "";
}
return ("?" +
entries
.filter(function (_) { return _[1] !== null; }) // If some value is NULL, do not append to URL
.map(function (_a) {
var _b = __read(_a, 2), key = _b[0], value = _b[1];
var valueString = value instanceof Date ? value.toISOString() : encodeURIComponent(String(value));
return "".concat(encodeURIComponent(key), "=").concat(valueString);
})
.join("&"));
}
//# sourceMappingURL=network.js.map