@web-atoms/core
Version:
374 lines (373 loc) • 14.9 kB
JavaScript
System.register(["tslib", "./AjaxOptions", "../../App", "../../Atom", "../../core/types", "../../di/Inject", "../../di/TypeKey", "../CacheService", "../JsonService", "./JsonError"], function (_export, _context) {
"use strict";
var __awaiter, __decorate, __metadata, __param, AjaxOptions, App, Atom, CancelToken, Inject, TypeKey, CacheService, JsonService, JsonError, ServiceParameter, BaseService_1, Path, Header, Query, Queries, Body, RawBody, BodyFormModel, XmlBody, Post, Get, Delete, Put, Patch, globalNS, BaseService;
function methodBuilder(method) {
return function (url, options) {
return function (target, propertyKey, descriptor) {
target.methods = target.methods || {};
const a = target.methods[propertyKey];
const oldFunction = descriptor.value;
descriptor.value = function (...args) {
if (this.testMode || Atom.designMode) {
console.log(`Test Design Mode: ${url} .. ${args.join(",")}`);
const ro = oldFunction.apply(this, args);
if (ro) {
return ro;
}
}
const jsCache = options ? options.jsCacheSeconds : 0;
if (jsCache) {
const cacheService = this.app.resolve(CacheService);
const jArgs = args.map(arg => arg instanceof CancelToken ? null : arg);
const key = `${this.constructor.name}:${method}:${url}:${JSON.stringify(jArgs)}`;
return cacheService.getOrCreate(key, e => {
e.ttlSeconds = jsCache;
return this.invoke(url, method, a, args, options);
});
}
return this.invoke(url, method, a, args, options);
};
};
};
}
function parameterBuilder(paramName, defaultValue) {
return function (key) {
return function (target, propertyKey, parameterIndex) {
target.methods = target.methods || {};
let a = target.methods[propertyKey];
if (!a) {
a = [];
target.methods[propertyKey] = a;
}
a[parameterIndex] = new ServiceParameter(paramName, key, defaultValue);
};
};
}
function Cancel(target, propertyKey, parameterIndex) {
if (!target.methods) {
target.methods = {};
}
let a = target.methods[propertyKey];
if (!a) {
a = [];
target.methods[propertyKey] = a;
}
a[parameterIndex] = new ServiceParameter("cancel", "");
}
function BaseUrl(baseUrl) {
return target => {
const key = TypeKey.get(target);
BaseService.baseUrls[key] = baseUrl;
};
}
_export({
Cancel: Cancel,
ServiceParameter: void 0,
default: BaseUrl
});
return {
setters: [function (_tslib) {
__awaiter = _tslib.__awaiter;
__decorate = _tslib.__decorate;
__metadata = _tslib.__metadata;
__param = _tslib.__param;
}, function (_AjaxOptions) {
AjaxOptions = _AjaxOptions.AjaxOptions;
}, function (_App) {
App = _App.App;
}, function (_Atom) {
Atom = _Atom.Atom;
}, function (_coreTypes) {
CancelToken = _coreTypes.CancelToken;
}, function (_diInject) {
Inject = _diInject.Inject;
}, function (_diTypeKey) {
TypeKey = _diTypeKey.TypeKey;
}, function (_CacheService) {
CacheService = _CacheService.default;
}, function (_JsonService) {
JsonService = _JsonService.JsonService;
}, function (_JsonError) {
JsonError = _JsonError.default;
}],
execute: function () {
_export("Path", Path = parameterBuilder("Path"));
_export("Header", Header = parameterBuilder("Header"));
_export("Query", Query = parameterBuilder("Query"));
_export("Queries", Queries = parameterBuilder("Queries")(""));
_export("Body", Body = parameterBuilder("Body")(""));
_export("RawBody", RawBody = parameterBuilder("RawBody")(""));
_export("BodyFormModel", BodyFormModel = parameterBuilder("BodyFormModel")(""));
_export("XmlBody", XmlBody = parameterBuilder("XmlBody")(""));
_export("Post", Post = methodBuilder("Post"));
_export("Get", Get = methodBuilder("Get"));
_export("Delete", Delete = methodBuilder("Delete"));
_export("Put", Put = methodBuilder("Put"));
_export("Patch", Patch = methodBuilder("Patch"));
_export("ServiceParameter", ServiceParameter = class ServiceParameter {
constructor(type, key, defaultValue) {
this.type = type;
this.key = key;
this.defaultValue = defaultValue;
this.type = type.toLowerCase();
this.key = key;
}
});
globalNS = typeof global !== "undefined" ? global : window;
if (!globalNS.XMLHttpRequest) {
globalNS.XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
}
_export("BaseService", BaseService = BaseService_1 = class BaseService {
constructor(app, jsonService) {
this.app = app;
this.jsonService = jsonService;
this.testMode = false;
this.showProgress = true;
this.showError = false;
this.methods = {};
this.methodReturns = {};
this.jsonOptions = null;
this.headers = null;
this.jsonOptions = Object.assign({}, this.jsonService.options);
}
encodeData(o) {
o.dataType = "application/json";
o.data = this.jsonService.stringify(o.data, this.jsonOptions);
o.contentType = "application/json";
return o;
}
sendResult(result, error) {
return new Promise((resolve, reject) => {
if (error) {
setTimeout(() => {
reject(error);
}, 1);
return;
}
setTimeout(() => {
resolve(result);
}, 1);
});
}
invoke(url, method, bag, values, methodOptions) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d, _e;
if (this.baseUrl === undefined) {
let p = Object.getPrototypeOf(this);
while (p) {
const t = TypeKey.get(p.constructor || p);
const bu = BaseService_1.baseUrls[t];
if (bu) {
this.baseUrl = bu;
break;
}
p = Object.getPrototypeOf(p);
}
if (this.baseUrl === undefined) {
this.baseUrl = null;
}
}
if (this.baseUrl) {
if (!/^\//.test(url)) {
url = `${this.baseUrl}${url}`;
}
}
const busyIndicator = this.showProgress ? this.app.createBusyIndicator({
title: url,
description: `${method} ${url}`
}) : null;
try {
url = UMD.resolvePath(url);
let options = new AjaxOptions();
options.method = method;
if (methodOptions) {
options.headers = methodOptions.headers;
options.dataType = methodOptions.accept;
}
const methodHeaders = options.headers = options.headers || {};
const headers = this.headers ? Object.assign(Object.assign({}, this.headers), methodHeaders) : methodHeaders;
if (!headers["X-Requested-With"]) {
headers["X-Requested-With"] = "XMLHttpRequest";
}
options.dataType = options.dataType || "application/json";
const jsonOptions = Object.assign(Object.assign({}, this.jsonOptions), methodOptions ? methodOptions.jsonOptions : {});
if (bag) {
for (let i = 0; i < bag.length; i++) {
const p = bag[i];
const vi = values[i];
const v = vi === undefined ? p.defaultValue : vi;
if (v instanceof CancelToken) {
options.cancel = v;
continue;
}
switch (p.type) {
case "path":
if (v === undefined) {
continue;
}
const vs = v + "";
const replacer = `{${p.key}}`;
url = url.split(replacer).join(vs);
break;
case "query":
if (v === undefined) {
continue;
}
if (url.indexOf("?") === -1) {
url += "?";
}
if (!/(\&|\?)$/.test(url)) {
url += "&";
}
url += `${encodeURIComponent(p.key)}=${encodeURIComponent(v)}`;
break;
case "queries":
if (url.indexOf("?") === -1) {
url += "?";
}
if (!/(\&|\?)$/.test(url)) {
url += "&";
}
for (const key in v) {
if (v.hasOwnProperty(key)) {
const element = v[key];
if (element !== undefined) {
url += `${encodeURIComponent(key)}=${encodeURIComponent(element)}&`;
}
}
}
break;
case "body":
options.data = v;
options = this.encodeData(options);
break;
case "bodyformmodel":
options.data = v;
break;
case "rawbody":
options.data = v;
break;
case "xmlbody":
options.contentType = "text/xml";
options.data = v;
break;
case "cancel":
options.cancel = v;
break;
case "header":
if (v === undefined) {
continue;
}
headers[p.key] = v;
break;
}
}
}
options.url = url;
const xhr = yield this.ajax(url, options);
if (/json/i.test(xhr.responseType)) {
const text = xhr.responseText;
const response = this.jsonService.parse(text, jsonOptions);
if (xhr.status >= 400) {
throw new JsonError(typeof response === "string" ? response : (_e = (_d = (_c = (_b = (_a = response.title) !== null && _a !== void 0 ? _a : response.detail) !== null && _b !== void 0 ? _b : response.message) !== null && _c !== void 0 ? _c : response.exceptionMessage) !== null && _d !== void 0 ? _d : text) !== null && _e !== void 0 ? _e : "Json Server Error", response);
}
if (methodOptions && methodOptions.returnHeaders) {
return {
headers: this.parseHeaders(xhr.responseHeaders),
value: response
};
}
return response;
}
if (xhr.status >= 400) {
throw new Error(xhr.responseText || "Server Error");
}
if (methodOptions && methodOptions.returnHeaders) {
return {
headers: this.parseHeaders(xhr.responseHeaders),
value: xhr.responseText
};
}
return xhr.responseText;
} finally {
if (busyIndicator) {
busyIndicator.dispose();
}
}
});
}
parseHeaders(headers) {
if (typeof headers === "object") {
return headers;
}
return (headers || "").split("\n").reduce((pv, c) => {
const cv = c.split(":");
pv[cv[0]] = (cv[1] || "").trim();
return pv;
}, {});
}
ajax(url, options) {
return __awaiter(this, void 0, void 0, function* () {
url = url || options.url;
if (options.cancel && options.cancel.cancelled) {
throw new Error("cancelled");
}
const xhr = new XMLHttpRequest();
return yield new Promise((resolve, reject) => {
if (options.cancel && options.cancel.cancelled) {
reject(options.cancel.cancelled);
return;
}
if (options.cancel) {
options.cancel.registerForCancel(r => {
xhr.abort();
reject(r);
return;
});
}
xhr.onreadystatechange = e => {
if (xhr.readyState === XMLHttpRequest.DONE) {
options.status = xhr.status;
options.responseText = xhr.responseText;
options.responseHeaders = xhr.getAllResponseHeaders();
const ct = xhr.getResponseHeader("content-type");
options.responseType = ct || xhr.responseType;
resolve(options);
}
};
xhr.open(options.method, url, true);
if (options.dataType) {
xhr.setRequestHeader("accept", options.dataType);
}
if (options.contentType) {
xhr.setRequestHeader("content-type", options.contentType);
}
const h = options.headers;
if (h) {
for (const key in h) {
if (h.hasOwnProperty(key)) {
const element = h[key];
xhr.setRequestHeader(key, element.toString());
}
}
}
try {
xhr.send(options.data);
} catch (e) {
options.status = xhr.status;
options.responseText = xhr.responseText;
options.responseHeaders = xhr.getAllResponseHeaders();
const ct = xhr.getResponseHeader("content-type");
options.responseType = ct || xhr.responseType;
resolve(options);
}
});
});
}
});
BaseService.baseUrls = {};
_export("BaseService", BaseService = BaseService_1 = __decorate([__param(0, Inject), __param(1, Inject), __metadata("design:paramtypes", [App, JsonService])], BaseService));
}
};
});
//# sourceMappingURL=RestService.js.map