@cloudbase/lowcode-deployer
Version:
deploy weda app
346 lines (345 loc) • 13.3 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TCBAPICloudApiService = exports.LocalStorage = void 0;
const request = require('request');
const fs_extra_1 = __importDefault(require("fs-extra"));
const path_1 = __importDefault(require("path"));
function isObject(x) {
return typeof x === 'object' && !Array.isArray(x) && x !== null;
}
// 移除对象中的空值,防止调用云 API 失败
function deepRemoveVoid(obj) {
if (Array.isArray(obj)) {
return obj.map(deepRemoveVoid);
}
else if (isObject(obj)) {
let result = {};
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
const value = obj[key];
if (typeof value !== 'undefined' && value !== null) {
result[key] = deepRemoveVoid(value);
}
}
}
return result;
}
else {
return obj;
}
}
function genSeqId() {
return Math.random().toString(16).slice(2);
}
class CommonError extends Error {
constructor(message, code = '-1', requestId = '', originData = undefined) {
if (typeof message === 'object') {
message.code = code;
message.requestId = requestId;
message.originData = originData;
return message;
}
else {
super(message);
this.code = code;
this.requestId = requestId;
this.originData = originData;
}
}
toString() {
return `[${this.code}] ${this.message} requestId:${this.requestId || ''}`;
}
toLocaleString() {
return `[${this.code}] ${this.message} requestId:${this.requestId || ''}`;
}
toJSON() {
return {
code: this.code,
message: this.message,
requestId: this.requestId,
};
}
}
class LocalStorage {
constructor(projectPath) {
this._map = new Map();
if (projectPath) {
this._path = path_1.default.join(projectPath, '.storage.json');
}
if (this._path && fs_extra_1.default.existsSync(this._path)) {
try {
const json = fs_extra_1.default.readJSONSync(this._path);
for (const key in json) {
this._map.set(key, json[key]);
}
}
catch (e) { }
}
}
getItem(key) {
return this._map.get(key);
}
setItem(key, value) {
this._map.set(key, value);
try {
if (this._path) {
fs_extra_1.default.writeJson(this._path, Object.fromEntries(this._map));
}
}
catch (e) { }
}
removeItem(key) {
this._map.delete(key);
try {
if (this._path) {
fs_extra_1.default.writeJson(this._path, Object.fromEntries(this._map));
}
}
catch (e) { }
}
}
exports.LocalStorage = LocalStorage;
class TCBAPICloudApiService {
constructor(options) {
const { env, service, version, apiOrigin, timeout = 60000, endpoint = '', uin, username, password, localstorage, packRes, } = options;
this._CREDENTIAL_KEY = `credentials_${env}`;
this._env = env;
this._serviceType = service;
this._version = version;
this._refreshTokenPromise = null;
this._uin = uin;
this._username = username;
this._password = password;
this._localstorage = localstorage || new LocalStorage();
this._packRes =
packRes ||
function (res) {
var _a;
return (_a = res.data) === null || _a === void 0 ? void 0 : _a.Response;
};
if ((process.env.IDAAS_ENDPOINT && !this._uin) ||
(!process.env.IDAAS_ENDPOINT && (!this._username || !this._password))) {
throw new Error('invalid credential');
}
const host = apiOrigin;
let protocol = 'http://';
let httpEndpoint = host;
const headers = {
origin: 'http://127.0.0.1',
referer: 'http://127.0.0.1',
};
if (endpoint) {
const url = new URL(endpoint);
protocol = `${url.protocol}//`;
httpEndpoint = url.host;
if (host) {
headers.host = host;
}
}
this._httpProfile = {
protocol,
httpEndpoint,
url: `${protocol}${httpEndpoint}`,
timeout,
headers,
};
}
async request(action, data = {}) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
const { access_token } = await this._getCredentials();
const reqData = deepRemoveVoid({ ...data });
try {
const res = await this.doReqeust({
url: `${(_a = this._httpProfile) === null || _a === void 0 ? void 0 : _a.url}/capi?env=${this._env}`,
method: 'post',
headers: { 'Content-Type': 'application/json;charset=UTF-8' },
body: {
env: this._env,
access_token: access_token,
serviceType: this._serviceType,
action,
version: this._version,
data: reqData,
},
}, { debug: true });
return this._packRes(res);
}
catch (e) {
if ((_e = (_d = (_c = (_b = e.originData) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.Response) === null || _d === void 0 ? void 0 : _d.Error) === null || _e === void 0 ? void 0 : _e.ReqeustId) {
e.requestId = (_j = (_h = (_g = (_f = e.originData) === null || _f === void 0 ? void 0 : _f.data) === null || _g === void 0 ? void 0 : _g.Response) === null || _h === void 0 ? void 0 : _h.Error) === null || _j === void 0 ? void 0 : _j.ReqeustId;
}
throw e;
}
}
async doReqeust({ url, headers: _headers = {}, body = {}, method = 'post' }, options) {
var _a;
const headers = { ...(_a = this._httpProfile) === null || _a === void 0 ? void 0 : _a.headers, ..._headers };
let seqId;
for (const key in headers) {
if (key.toLowerCase() === 'x-seqid') {
seqId = headers[key];
break;
}
}
if (!seqId) {
seqId = genSeqId();
headers['x-seqid'] = seqId;
}
return new Promise((resolve, reject) => {
var _a;
request({
url,
method,
headers,
body,
timeout: (_a = this._httpProfile) === null || _a === void 0 ? void 0 : _a.timeout,
json: true,
strictSSL: false,
}, function (err, res, data) {
if (err) {
reject(new CommonError(err));
}
else if (res.statusCode >= 300) {
let message;
try {
message = data.message || res.statusCode;
}
catch (e) { }
reject(new CommonError(`${url} 请求响应状态异常 ${message}`, res.statusCode, seqId, data));
}
else if (data.code) {
reject(new CommonError(data.message, data.code, seqId, data));
}
else {
resolve(data);
}
});
});
}
_isExpired(credentials) {
if (credentials) {
if (!credentials.expires_at || new Date(credentials.expires_at).getTime() < Date.now()) {
return true;
}
return false;
}
return true;
}
async _getCredentials() {
var _a, _b, _c, _d, _e, _f, _g, _h;
const cache = this._localstorage.getItem(this._CREDENTIAL_KEY);
if (!this._isExpired(cache)) {
return cache;
}
if (cache === null || cache === void 0 ? void 0 : cache.refresh_token) {
return this._refreshToken(cache.refresh_token);
}
const seqId = genSeqId();
let error;
try {
let res;
if (process.env.IDAAS_ENDPOINT) {
res = await this.doReqeust({
url: `${process.env.IDAAS_ENDPOINT}/cloudbase.auth.v2.MgrV2/DescribeAdministratorToken`,
method: 'post',
headers: {
['x-request-id']: seqId,
['x-seqid']: seqId,
},
body: {
RequestId: seqId,
Uin: this._uin,
AppId: 1,
SubAccountUin: this._uin,
Region: process.env.PRIVATE_CLOUD_API_REGION || 'chongqing',
EnvId: this._env,
},
}, { debug: true });
if ((_a = res.Response) === null || _a === void 0 ? void 0 : _a.Error) {
throw new CommonError(`DescribeAdministratorToken 请求响应状态异常 ${res.Response.Error.Message}`, (_b = res.Response.Error) === null || _b === void 0 ? void 0 : _b.Code, seqId, res);
}
const { TokenType, AccessToken, RefreshToken, ExpiresIn } = res.Response || {};
res = {
token_type: TokenType,
access_token: AccessToken,
refresh_token: RefreshToken,
expires_in: ExpiresIn,
};
}
else {
res = await this.doReqeust({
url: `${((_c = this._httpProfile) === null || _c === void 0 ? void 0 : _c.protocol) && ((_d = this._httpProfile.headers) === null || _d === void 0 ? void 0 : _d.host)
? `${(_e = this._httpProfile) === null || _e === void 0 ? void 0 : _e.protocol}${(_f = this._httpProfile.headers) === null || _f === void 0 ? void 0 : _f.host}`
: (_g = this._httpProfile) === null || _g === void 0 ? void 0 : _g.url}/auth/v1/signin?clientId=${this._env}`,
method: 'post',
headers: {
['x-request-id']: seqId,
['x-seqid']: seqId,
},
body: { username: this._username, password: this._password, isEncrypt: true },
}, { debug: true });
if (res === null || res === void 0 ? void 0 : res.error) {
throw new CommonError(res.error_description, res.error, seqId, res);
}
}
this._setCredentials(res);
return res;
}
catch (e) {
if ((_h = e.originData) === null || _h === void 0 ? void 0 : _h.error) {
error = e.originData;
}
else {
this._setCredentials(null);
throw e;
}
}
if (error === null || error === void 0 ? void 0 : error.error) {
this._setCredentials(null);
throw new CommonError(`/auth/v1/signin ${error.error_description}`, error.error || 'unreachable', error.requestId || seqId, error);
}
}
_setCredentials(credential) {
if (!credential) {
this._localstorage.removeItem(this._CREDENTIAL_KEY);
return;
}
if (!credential.expires_at && credential.expires_in) {
credential.expires_at = Date.now() + credential.expires_in * 1000;
}
this._localstorage.setItem(this._CREDENTIAL_KEY, credential);
}
async _refreshToken(refreshToken) {
var _a;
const seqId = genSeqId();
if (!this._refreshTokenPromise) {
this._refreshTokenPromise = this.doReqeust({
url: `${(_a = this._httpProfile) === null || _a === void 0 ? void 0 : _a.url}/auth/v1/token`,
headers: { ['x-request-id']: seqId, ['x-seqid']: seqId },
body: {
client_id: this._env,
grant_type: 'refresh_token',
refresh_token: refreshToken,
},
}).then((res) => {
this._refreshTokenPromise = null;
return res;
}, (e) => {
this._refreshTokenPromise = null;
this._setCredentials(null);
throw e;
});
}
const res = await this._refreshTokenPromise;
if (res.error) {
this._setCredentials(null);
throw new CommonError(`/auth/v1/token ${res.error_description}`, res.error || 'unreachable', res.requestId || seqId, res);
}
this._setCredentials(res);
return res;
}
}
exports.TCBAPICloudApiService = TCBAPICloudApiService;