231 lines
7.9 KiB
JavaScript
231 lines
7.9 KiB
JavaScript
"use strict";
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
const tslib_1 = require("tslib");
|
||
const assert_1 = tslib_1.__importDefault(require("assert"));
|
||
const stream_1 = require("stream");
|
||
const url_1 = tslib_1.__importDefault(require("url"));
|
||
const types_1 = require("../types");
|
||
class SimpleConnector {
|
||
static ASPECT_ROUTER = '/aspect';
|
||
static BRIDGE_ROUTER = '/bridge';
|
||
static SUBSCRIBE_ROUTER = process.env.OAK_SUBSCRIBE_ROUTER || '/subscribe';
|
||
static SUBSCRIBE_POINT_ROUTER = '/subscribePoint';
|
||
static ENDPOINT_ROUTER = '/endpoint';
|
||
serverUrl;
|
||
serverAspectUrl;
|
||
serverBridgeUrl;
|
||
serverSubscribePointUrl;
|
||
configuration;
|
||
makeException;
|
||
constructor(configuration, makeException) {
|
||
this.configuration = configuration;
|
||
const { routerPrefixes, http } = configuration;
|
||
const { ssl, hostname, port, path } = http;
|
||
const protocol = ssl ? 'https:' : 'http:';
|
||
let serverUrl = `${protocol}//${hostname}`;
|
||
this.serverUrl = serverUrl;
|
||
if (typeof port === 'number') {
|
||
serverUrl += `:${port}`;
|
||
}
|
||
if (path) {
|
||
if (path.startsWith('/')) {
|
||
serverUrl += path;
|
||
}
|
||
else {
|
||
serverUrl += `/${path}`;
|
||
}
|
||
}
|
||
this.serverAspectUrl = `${serverUrl}${routerPrefixes?.aspect || SimpleConnector.ASPECT_ROUTER}`;
|
||
this.serverBridgeUrl = `${serverUrl}${routerPrefixes?.bridge || SimpleConnector.BRIDGE_ROUTER}`;
|
||
this.serverSubscribePointUrl = `${serverUrl}${routerPrefixes?.getSubscribePoint ||
|
||
SimpleConnector.SUBSCRIBE_POINT_ROUTER}`;
|
||
this.makeException = makeException;
|
||
}
|
||
async makeHeadersAndBody(name, data, context) {
|
||
const cxtStr = context ? await context.toString() : '{}';
|
||
const headers = {
|
||
'oak-cxt': cxtStr,
|
||
'oak-aspect': name,
|
||
};
|
||
if (process.env.OAK_PLATFORM !== 'wechatMp') {
|
||
if (data instanceof FormData) {
|
||
return {
|
||
headers,
|
||
body: data,
|
||
};
|
||
}
|
||
}
|
||
return {
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
...headers,
|
||
},
|
||
body: JSON.stringify(data),
|
||
};
|
||
}
|
||
;
|
||
async parseAspectResult(response) {
|
||
if (response.status > 299) {
|
||
const err = new types_1.OakServerProxyException(`网络请求返回status是${response.status}`);
|
||
throw err;
|
||
}
|
||
const message = response.headers.get('oak-message');
|
||
const responseType = response.headers.get('Content-Type') ||
|
||
response.headers.get('content-type');
|
||
if (responseType?.toLocaleLowerCase().match(/application\/json/i)) {
|
||
const { exception, result, opRecords } = await response.json();
|
||
if (exception) {
|
||
throw this.makeException(exception);
|
||
}
|
||
return {
|
||
result,
|
||
opRecords,
|
||
message,
|
||
};
|
||
}
|
||
else if (responseType
|
||
?.toLocaleLowerCase()
|
||
.match(/application\/octet-stream/i)) {
|
||
const result = await response.arrayBuffer();
|
||
return {
|
||
result,
|
||
message,
|
||
};
|
||
}
|
||
else {
|
||
throw new Error(`尚不支持的content-type类型${responseType}`);
|
||
}
|
||
}
|
||
async callAspect(name, params, context) {
|
||
const { headers, body } = await this.makeHeadersAndBody(name, params, context);
|
||
let response;
|
||
try {
|
||
response = await global.fetch(this.serverAspectUrl, {
|
||
method: 'POST',
|
||
headers,
|
||
body,
|
||
});
|
||
}
|
||
catch (err) {
|
||
// fetch返回异常一定是网络异常
|
||
throw new types_1.OakNetworkException(`接口请求时发生网络异常`);
|
||
}
|
||
return this.parseAspectResult(response);
|
||
}
|
||
getRouter() {
|
||
return this.configuration.routerPrefixes?.aspect || SimpleConnector.ASPECT_ROUTER;
|
||
}
|
||
getSubscribeRouter() {
|
||
return this.configuration.routerPrefixes?.subscribe || SimpleConnector.SUBSCRIBE_ROUTER;
|
||
}
|
||
getSubscribePointRouter() {
|
||
return this.configuration.routerPrefixes?.getSubscribePoint || SimpleConnector.SUBSCRIBE_POINT_ROUTER;
|
||
}
|
||
async getSubscribePoint() {
|
||
let response;
|
||
try {
|
||
response = await global.fetch(this.serverSubscribePointUrl);
|
||
}
|
||
catch (err) {
|
||
throw new types_1.OakNetworkException();
|
||
}
|
||
if (response.status > 299) {
|
||
const err = new types_1.OakServerProxyException(`网络请求返回status是${response.status}`);
|
||
throw err;
|
||
}
|
||
const message = response.headers.get('oak-message');
|
||
const responseType = response.headers.get('Content-Type') ||
|
||
response.headers.get('content-type');
|
||
if (responseType?.toLocaleLowerCase().match(/application\/json/i)) {
|
||
const { url, path, port, namespace } = await response.json();
|
||
let url2 = url || this.serverUrl;
|
||
if (port) {
|
||
url2 += `:${port}`;
|
||
}
|
||
if (namespace) {
|
||
url2 += namespace;
|
||
}
|
||
return {
|
||
url: url2,
|
||
path,
|
||
};
|
||
}
|
||
else {
|
||
throw new Error(`尚不支持的content-type类型${responseType}`);
|
||
}
|
||
}
|
||
getEndpointRouter() {
|
||
return this.configuration.routerPrefixes?.endpoint || SimpleConnector.ENDPOINT_ROUTER;
|
||
}
|
||
parseRequest(headers, body, files) {
|
||
const { 'oak-cxt': oakCxtStr, 'oak-aspect': aspectName } = headers;
|
||
(0, assert_1.default)(typeof oakCxtStr === 'string' || oakCxtStr === undefined);
|
||
(0, assert_1.default)(typeof aspectName === 'string');
|
||
return {
|
||
contextString: oakCxtStr,
|
||
aspectName,
|
||
/* data: !files ? body : {
|
||
data: body,
|
||
files,
|
||
}, */ // 下个版本再改
|
||
data: files ? Object.assign({}, body, files) : body,
|
||
};
|
||
}
|
||
async serializeResult(result, opRecords, headers, body, message) {
|
||
if (result instanceof stream_1.Stream || result instanceof Buffer) {
|
||
return {
|
||
body: result,
|
||
headers: {
|
||
'oak-message': message,
|
||
},
|
||
};
|
||
}
|
||
return {
|
||
body: {
|
||
result,
|
||
opRecords,
|
||
},
|
||
headers: {
|
||
'oak-message': message,
|
||
},
|
||
};
|
||
}
|
||
serializeException(exception, headers, body) {
|
||
return {
|
||
body: {
|
||
exception: exception.toString(),
|
||
},
|
||
};
|
||
}
|
||
getBridgeRouter() {
|
||
return SimpleConnector.BRIDGE_ROUTER;
|
||
}
|
||
/**
|
||
* 通过本地服务器桥接访问外部资源的url
|
||
* @param url
|
||
* @param headers
|
||
*/
|
||
makeBridgeUrl(url, headers) {
|
||
// if (process.env.PROD !== 'true') {
|
||
// console.warn('在development下无法通过bridge访问资源,将直接访问,可能失败', url);
|
||
// return url;
|
||
// }
|
||
const encodeUrl = encodeURIComponent(url);
|
||
return `${this.serverBridgeUrl}?url=${encodeUrl}`;
|
||
}
|
||
parseBridgeRequestQuery(urlParams) {
|
||
const search = new url_1.default.URLSearchParams(urlParams);
|
||
const url = search.get('url');
|
||
const headers = search.get('headers');
|
||
return {
|
||
url,
|
||
headers: headers && JSON.parse(headers),
|
||
};
|
||
}
|
||
async getFullData() {
|
||
console.error('前后台模式下暂时不支持此操作,请到数据库查看数据');
|
||
return {};
|
||
}
|
||
}
|
||
exports.default = SimpleConnector;
|